diff --git a/sample/chromium/chrome_subsetter.cc b/sample/chromium/chrome_subsetter.cc
new file mode 100644
index 0000000..df15c18
--- /dev/null
+++ b/sample/chromium/chrome_subsetter.cc
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+
+#include <vector>
+#include <string>
+#include <sstream>
+
+#include "sfntly/port/type.h"
+#include "font_subsetter.h"
+
+template <typename T>
+class HexTo {
+ public:
+  explicit HexTo(const char* in) {
+    std::stringstream ss;
+    ss << std::hex << in;
+    ss >> value_;
+  }
+  operator T() const { return value_; }
+
+ private:
+  T value_;
+};
+
+bool LoadFile(const char* input_file_path, sfntly::ByteVector* input_buffer) {
+  assert(input_file_path);
+  assert(input_buffer);
+
+  FILE* input_file = NULL;
+#if defined WIN32
+  fopen_s(&input_file, input_file_path, "rb");
+#else
+  input_file = fopen(input_file_path, "rb");
+#endif
+  if (input_file == NULL) {
+    return false;
+  }
+  fseek(input_file, 0, SEEK_END);
+  size_t file_size = ftell(input_file);
+  fseek(input_file, 0, SEEK_SET);
+  input_buffer->resize(file_size);
+  size_t bytes_read = fread(&((*input_buffer)[0]), 1, file_size, input_file);
+  fclose(input_file);
+  return bytes_read == file_size;
+}
+
+bool SaveFile(const char* output_file_path, const unsigned char* output_buffer,
+              int buffer_length) {
+  int byte_count = 0;
+  if (buffer_length > 0) {
+    FILE* output_file = NULL;
+#if defined WIN32
+    fopen_s(&output_file, output_file_path, "wb");
+#else
+    output_file = fopen(output_file_path, "wb");
+#endif
+    if (output_file) {
+      byte_count = fwrite(output_buffer, 1, buffer_length, output_file);
+      fflush(output_file);
+      fclose(output_file);
+    }
+    return buffer_length == byte_count;
+  }
+  return false;
+}
+
+bool StringToGlyphId(const char* input, std::vector<unsigned int>* glyph_ids) {
+  assert(input);
+  std::string hex_csv = input;
+  size_t start = 0;
+  size_t end = hex_csv.find_first_of(",");
+  while (end != std::string::npos) {
+    glyph_ids->push_back(
+        HexTo<unsigned int>(hex_csv.substr(start, end - start).c_str()));
+    start = end + 1;
+    end = hex_csv.find_first_of(",", start);
+  }
+  glyph_ids->push_back(HexTo<unsigned int>(hex_csv.substr(start).c_str()));
+  return glyph_ids->size() > 0;
+}
+
+int main(int argc, char** argv) {
+  if (argc < 5) {
+    fprintf(stderr,
+        "Usage: %s <input path> <output path> <font name> <glyph ids>\n",
+        argv[0]);
+    fprintf(stderr, "\tGlyph ids are comma separated hex values\n");
+    fprintf(stderr, "\te.g. 20,1a,3b,4f\n");
+    return 0;
+  }
+
+  sfntly::ByteVector input_buffer;
+  if (!LoadFile(argv[1], &input_buffer)) {
+    fprintf(stderr, "ERROR: unable to load font file %s\n", argv[1]);
+    return 0;
+  }
+
+  std::vector<unsigned int> glyph_ids;
+  if (!StringToGlyphId(argv[4], &glyph_ids)) {
+    fprintf(stderr, "ERROR: unable to parse input glyph id\n");
+    return 0;
+  }
+
+  unsigned char* output_buffer = NULL;
+  int output_length =
+      SfntlyWrapper::SubsetFont(argv[3],
+                                &(input_buffer[0]),
+                                input_buffer.size(),
+                                &(glyph_ids[0]),
+                                glyph_ids.size(),
+                                &output_buffer);
+
+  int result = SaveFile(argv[2], output_buffer, output_length) ? 1 : 0;
+  delete[] output_buffer;
+  return result;
+}
diff --git a/sample/chromium/font_subsetter.cc b/sample/chromium/font_subsetter.cc
new file mode 100644
index 0000000..14f5494
--- /dev/null
+++ b/sample/chromium/font_subsetter.cc
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "font_subsetter.h"
+
+#include "subsetter_impl.h"
+
+int SfntlyWrapper::SubsetFont(const char* font_name,
+                              const unsigned char* original_font,
+                              size_t font_size,
+                              const unsigned int* glyph_ids,
+                              size_t glyph_count,
+                              unsigned char** output_buffer) {
+  if (output_buffer == NULL ||
+      original_font == NULL || font_size == 0 ||
+      glyph_ids == NULL || glyph_count == 0) {
+    return 0;
+  }
+
+  sfntly::SubsetterImpl subsetter;
+  if (!subsetter.LoadFont(font_name, original_font, font_size)) {
+    return -1;  // Load error or font not found.
+  }
+
+  return subsetter.SubsetFont(glyph_ids, glyph_count, output_buffer);
+}
diff --git a/sample/chromium/font_subsetter.h b/sample/chromium/font_subsetter.h
new file mode 100644
index 0000000..07b1b5b
--- /dev/null
+++ b/sample/chromium/font_subsetter.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+// File is originally from Chromium third_party/sfntly/src/subsetter.
+// Use as test case in sfntly so that problems can be caught in upstream early.
+#ifndef SFNTLY_CPP_SRC_TEST_FONT_SUBSETTER_H_
+#define SFNTLY_CPP_SRC_TEST_FONT_SUBSETTER_H_
+
+#include <cstddef>
+
+class SfntlyWrapper {
+ public:
+
+  // Font subsetting API
+  //
+  // Input TTF/TTC/OTF fonts, specify the glyph IDs to subset, and the subset
+  // font is returned in |output_buffer| (caller to delete[]).  Return value is
+  // the length of output_buffer allocated.
+  //
+  // If subsetting fails, a negative value is returned.  If none of the glyph
+  // IDs specified is found, the function will return 0.
+  //
+  // |font_name|      Font name, required for TTC files.  If specified NULL,
+  //                  the first available font is selected.
+  // |original_font|  Original font file contents.
+  // |font_size|      Size of |original_font| in bytes.
+  // |glyph_ids|      Glyph IDs to subset.  If the specified glyph ID is not
+  //                  found in the font file, it will be ignored silently.
+  // |glyph_count|    Number of glyph IDs in |glyph_ids|
+  // |output_buffer|  Generated subset font.  Caller to delete[].
+  static int SubsetFont(const char* font_name,
+                        const unsigned char* original_font,
+                        size_t font_size,
+                        const unsigned int* glyph_ids,
+                        size_t glyph_count,
+                        unsigned char** output_buffer);
+};
+
+#endif  // SFNTLY_CPP_SRC_TEST_FONT_SUBSETTER_H_
diff --git a/sample/chromium/subsetter_impl.cc b/sample/chromium/subsetter_impl.cc
new file mode 100644
index 0000000..528e336
--- /dev/null
+++ b/sample/chromium/subsetter_impl.cc
@@ -0,0 +1,785 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "subsetter_impl.h"
+
+#include <string.h>
+
+#include <algorithm>
+#include <iterator>
+#include <map>
+#include <set>
+
+#include "sfntly/table/bitmap/eblc_table.h"
+#include "sfntly/table/bitmap/ebdt_table.h"
+#include "sfntly/table/bitmap/index_sub_table.h"
+#include "sfntly/table/bitmap/index_sub_table_format1.h"
+#include "sfntly/table/bitmap/index_sub_table_format2.h"
+#include "sfntly/table/bitmap/index_sub_table_format3.h"
+#include "sfntly/table/bitmap/index_sub_table_format4.h"
+#include "sfntly/table/bitmap/index_sub_table_format5.h"
+#include "sfntly/table/core/name_table.h"
+#include "sfntly/tag.h"
+#include "sfntly/data/memory_byte_array.h"
+#include "sfntly/port/memory_input_stream.h"
+#include "sfntly/port/memory_output_stream.h"
+
+#if defined U_USING_ICU_NAMESPACE
+  U_NAMESPACE_USE
+#endif
+
+namespace {
+
+using namespace sfntly;
+
+// The bitmap tables must be greater than 16KB to trigger bitmap subsetter.
+static const int BITMAP_SIZE_THRESHOLD = 16384;
+
+void ConstructName(UChar* name_part, UnicodeString* name, int32_t name_id) {
+  switch (name_id) {
+    case NameId::kFullFontName:
+      *name = name_part;
+      break;
+    case NameId::kFontFamilyName:
+    case NameId::kPreferredFamily:
+    case NameId::kWWSFamilyName: {
+      UnicodeString original = *name;
+      *name = name_part;
+      *name += original;
+      break;
+    }
+    case NameId::kFontSubfamilyName:
+    case NameId::kPreferredSubfamily:
+    case NameId::kWWSSubfamilyName:
+      *name += name_part;
+      break;
+    default:
+      // This name part is not used to construct font name (e.g. copyright).
+      // Simply ignore it.
+      break;
+  }
+}
+
+int32_t HashCode(int32_t platform_id, int32_t encoding_id, int32_t language_id,
+                 int32_t name_id) {
+  int32_t result = platform_id << 24 | encoding_id << 16 | language_id << 8;
+  if (name_id == NameId::kFullFontName) {
+    result |= 0xff;
+  } else if (name_id == NameId::kPreferredFamily ||
+             name_id == NameId::kPreferredSubfamily) {
+    result |= 0xf;
+  } else if (name_id == NameId::kWWSFamilyName ||
+             name_id == NameId::kWWSSubfamilyName) {
+    result |= 1;
+  }
+  return result;
+}
+
+bool HasName(const char* font_name, Font* font) {
+  UnicodeString font_string = UnicodeString::fromUTF8(font_name);
+  if (font_string.isEmpty())
+    return false;
+  UnicodeString regular_suffix = UnicodeString::fromUTF8(" Regular");
+  UnicodeString alt_font_string = font_string;
+  alt_font_string += regular_suffix;
+
+  typedef std::map<int32_t, UnicodeString> NameMap;
+  NameMap names;
+  NameTablePtr name_table = down_cast<NameTable*>(font->GetTable(Tag::name));
+  if (name_table == NULL) {
+    return false;
+  }
+
+  for (int32_t i = 0; i < name_table->NameCount(); ++i) {
+    switch (name_table->NameId(i)) {
+      case NameId::kFontFamilyName:
+      case NameId::kFontSubfamilyName:
+      case NameId::kFullFontName:
+      case NameId::kPreferredFamily:
+      case NameId::kPreferredSubfamily:
+      case NameId::kWWSFamilyName:
+      case NameId::kWWSSubfamilyName: {
+        UChar* name_part = name_table->Name(i);
+        if (name_part == NULL) {
+          continue;
+        }
+        int32_t hash_code = HashCode(name_table->PlatformId(i),
+                                     name_table->EncodingId(i),
+                                     name_table->LanguageId(i),
+                                     name_table->NameId(i));
+        ConstructName(name_part, &(names[hash_code]), name_table->NameId(i));
+        delete[] name_part;
+        break;
+      }
+      default:
+        break;
+    }
+  }
+
+  if (!names.empty()) {
+    for (NameMap::iterator i = names.begin(), e = names.end(); i != e; ++i) {
+      if (i->second.caseCompare(font_string, 0) == 0 ||
+          i->second.caseCompare(alt_font_string, 0) == 0) {
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
+Font* FindFont(const char* font_name, const FontArray& font_array) {
+  if (font_array.empty() || font_array[0] == NULL) {
+    return NULL;
+  }
+
+  if (font_name && strlen(font_name)) {
+    for (FontArray::const_iterator i = font_array.begin(), e = font_array.end();
+         i != e; ++i) {
+      if (HasName(font_name, i->p_)) {
+        return i->p_;
+      }
+    }
+  }
+
+  return font_array[0].p_;
+}
+
+bool ResolveCompositeGlyphs(GlyphTable* glyph_table,
+                            LocaTable* loca_table,
+                            const unsigned int* glyph_ids,
+                            size_t glyph_count,
+                            IntegerSet* glyph_id_processed) {
+  if (glyph_table == NULL || loca_table == NULL ||
+      glyph_ids == NULL || glyph_count == 0 || glyph_id_processed == NULL) {
+    return false;
+  }
+
+  // Sort and uniquify glyph ids.
+  IntegerSet glyph_id_remaining;
+  glyph_id_remaining.insert(0);  // Always include glyph id 0.
+  for (size_t i = 0; i < glyph_count; ++i) {
+    glyph_id_remaining.insert(glyph_ids[i]);
+  }
+
+  // Identify if any given glyph id maps to a composite glyph.  If so, include
+  // the glyphs referenced by that composite glyph.
+  while (!glyph_id_remaining.empty()) {
+    IntegerSet comp_glyph_id;
+    for (IntegerSet::iterator i = glyph_id_remaining.begin(),
+                              e = glyph_id_remaining.end(); i != e; ++i) {
+      if (*i < 0 || *i >= loca_table->num_glyphs()) {
+        // Invalid glyph id, ignore.
+        continue;
+      }
+
+      int32_t length = loca_table->GlyphLength(*i);
+      if (length == 0) {
+        // Empty glyph, ignore.
+        continue;
+      }
+      int32_t offset = loca_table->GlyphOffset(*i);
+
+      GlyphPtr glyph;
+      glyph.Attach(glyph_table->GetGlyph(offset, length));
+      if (glyph == NULL) {
+        // Error finding glyph, ignore.
+        continue;
+      }
+
+      if (glyph->GlyphType() == GlyphType::kComposite) {
+        Ptr<GlyphTable::CompositeGlyph> comp_glyph =
+            down_cast<GlyphTable::CompositeGlyph*>(glyph.p_);
+        for (int32_t j = 0; j < comp_glyph->NumGlyphs(); ++j) {
+          int32_t glyph_id = comp_glyph->GlyphIndex(j);
+          if (glyph_id_processed->find(glyph_id) == glyph_id_processed->end() &&
+              glyph_id_remaining.find(glyph_id) == glyph_id_remaining.end()) {
+            comp_glyph_id.insert(comp_glyph->GlyphIndex(j));
+          }
+        }
+      }
+
+      glyph_id_processed->insert(*i);
+    }
+
+    glyph_id_remaining.clear();
+    glyph_id_remaining = comp_glyph_id;
+  }
+
+  return true;
+}
+
+bool SetupGlyfBuilders(Font::Builder* font_builder,
+                       GlyphTable* glyph_table,
+                       LocaTable* loca_table,
+                       const IntegerSet& glyph_ids) {
+  if (!font_builder || !glyph_table || !loca_table) {
+    return false;
+  }
+
+  GlyphTableBuilderPtr glyph_table_builder =
+      down_cast<GlyphTable::Builder*>(font_builder->NewTableBuilder(Tag::glyf));
+  LocaTableBuilderPtr loca_table_builder =
+      down_cast<LocaTable::Builder*>(font_builder->NewTableBuilder(Tag::loca));
+  if (glyph_table_builder == NULL || loca_table_builder == NULL) {
+    // Out of memory.
+    return false;
+  }
+
+  // Extract glyphs and setup loca list.
+  IntegerList loca_list;
+  loca_list.resize(loca_table->num_glyphs());
+  loca_list.push_back(0);
+  int32_t last_glyph_id = 0;
+  int32_t last_offset = 0;
+  GlyphTable::GlyphBuilderList* glyph_builders =
+      glyph_table_builder->GlyphBuilders();
+  for (IntegerSet::const_iterator i = glyph_ids.begin(), e = glyph_ids.end();
+                                  i != e; ++i) {
+    int32_t length = loca_table->GlyphLength(*i);
+    int32_t offset = loca_table->GlyphOffset(*i);
+
+    GlyphPtr glyph;
+    glyph.Attach(glyph_table->GetGlyph(offset, length));
+
+    // Add glyph to new glyf table.
+    ReadableFontDataPtr data = glyph->ReadFontData();
+    WritableFontDataPtr copy_data;
+    copy_data.Attach(WritableFontData::CreateWritableFontData(data->Length()));
+    data->CopyTo(copy_data);
+    GlyphBuilderPtr glyph_builder;
+    glyph_builder.Attach(glyph_table_builder->GlyphBuilder(copy_data));
+    glyph_builders->push_back(glyph_builder);
+
+    // Configure loca list.
+    for (int32_t j = last_glyph_id + 1; j <= *i; ++j) {
+      loca_list[j] = last_offset;
+    }
+    last_offset += length;
+    loca_list[*i + 1] = last_offset;
+    last_glyph_id = *i;
+  }
+  for (int32_t j = last_glyph_id + 1; j <= loca_table->num_glyphs(); ++j) {
+    loca_list[j] = last_offset;
+  }
+  loca_table_builder->SetLocaList(&loca_list);
+
+  return true;
+}
+
+bool HasOverlap(int32_t range_begin, int32_t range_end,
+                const IntegerSet& glyph_ids) {
+  if (range_begin == range_end) {
+    return glyph_ids.find(range_begin) != glyph_ids.end();
+  } else if (range_end > range_begin) {
+    IntegerSet::const_iterator left = glyph_ids.lower_bound(range_begin);
+    IntegerSet::const_iterator right = glyph_ids.lower_bound(range_end);
+    return right != left;
+  }
+  return false;
+}
+
+// Initialize builder, returns false if glyph_id subset is not covered.
+// Not thread-safe, caller to ensure object life-time.
+bool InitializeBitmapBuilder(EbdtTable::Builder* ebdt, EblcTable::Builder* eblc,
+                             const IntegerSet& glyph_ids) {
+  BitmapLocaList loca_list;
+  BitmapSizeTableBuilderList* strikes = eblc->BitmapSizeBuilders();
+
+  // Note: Do not call eblc_builder->GenerateLocaList(&loca_list) and then
+  //       ebdt_builder->SetLoca(loca_list).  For fonts like SimSun, there are
+  //       >28K glyphs inside, where a typical usage will be <1K glyphs.  Doing
+  //       the calls improperly will result in creation of >100K objects that
+  //       will be destroyed immediately, inducing significant slowness.
+  IntegerList removed_strikes;
+  for (size_t i = 0; i < strikes->size(); i++) {
+    if (!HasOverlap((*strikes)[i]->StartGlyphIndex(),
+                    (*strikes)[i]->EndGlyphIndex(), glyph_ids)) {
+      removed_strikes.push_back(i);
+      continue;
+    }
+
+    IndexSubTableBuilderList* index_builders =
+        (*strikes)[i]->IndexSubTableBuilders();
+    IntegerList removed_indexes;
+    BitmapGlyphInfoMap info_map;
+    for (size_t j = 0; j < index_builders->size(); ++j) {
+      if ((*index_builders)[j] == NULL) {
+        // Subtable is malformed, let's just skip it.
+        removed_indexes.push_back(j);
+        continue;
+      }
+      int32_t first_glyph_id = (*index_builders)[j]->first_glyph_index();
+      int32_t last_glyph_id = (*index_builders)[j]->last_glyph_index();
+      if (!HasOverlap(first_glyph_id, last_glyph_id, glyph_ids)) {
+        removed_indexes.push_back(j);
+        continue;
+      }
+      for (IntegerSet::const_iterator gid = glyph_ids.begin(),
+                                      gid_end = glyph_ids.end();
+                                      gid != gid_end; gid++) {
+        if (*gid < first_glyph_id) {
+          continue;
+        }
+        if (*gid > last_glyph_id) {
+          break;
+        }
+        BitmapGlyphInfoPtr info;
+        info.Attach((*index_builders)[j]->GlyphInfo(*gid));
+        if (info && info->length()) {  // Do not include gid without bitmap
+          info_map[*gid] = info;
+        }
+      }
+    }
+    if (!info_map.empty()) {
+      loca_list.push_back(info_map);
+    } else {
+      removed_strikes.push_back(i);  // Detected null entries.
+    }
+
+    // Remove unused index sub tables
+    for (IntegerList::reverse_iterator j = removed_indexes.rbegin(),
+                                       e = removed_indexes.rend();
+                                       j != e; j++) {
+      index_builders->erase(index_builders->begin() + *j);
+    }
+  }
+  if (removed_strikes.size() == strikes->size() || loca_list.empty()) {
+    return false;
+  }
+
+  for (IntegerList::reverse_iterator i = removed_strikes.rbegin(),
+                                     e = removed_strikes.rend(); i != e; i++) {
+    strikes->erase(strikes->begin() + *i);
+  }
+
+  if (strikes->empty()) {  // no glyph covered, can safely drop the builders.
+    return false;
+  }
+
+  ebdt->SetLoca(&loca_list);
+  ebdt->GlyphBuilders();  // Initialize the builder.
+  return true;
+}
+
+void CopyBigGlyphMetrics(BigGlyphMetrics::Builder* source,
+                         BigGlyphMetrics::Builder* target) {
+  target->SetHeight(static_cast<byte_t>(source->Height()));
+  target->SetWidth(static_cast<byte_t>(source->Width()));
+  target->SetHoriBearingX(static_cast<byte_t>(source->HoriBearingX()));
+  target->SetHoriBearingY(static_cast<byte_t>(source->HoriBearingY()));
+  target->SetHoriAdvance(static_cast<byte_t>(source->HoriAdvance()));
+  target->SetVertBearingX(static_cast<byte_t>(source->VertBearingX()));
+  target->SetVertBearingY(static_cast<byte_t>(source->VertBearingY()));
+  target->SetVertAdvance(static_cast<byte_t>(source->VertAdvance()));
+}
+
+CALLER_ATTACH IndexSubTable::Builder*
+ConstructIndexFormat4(IndexSubTable::Builder* b, const BitmapGlyphInfoMap& loca,
+                      int32_t* image_data_offset) {
+  IndexSubTableFormat4BuilderPtr builder4;
+  builder4.Attach(IndexSubTableFormat4::Builder::CreateBuilder());
+  CodeOffsetPairBuilderList offset_pairs;
+
+  size_t offset = 0;
+  int32_t lower_bound = b->first_glyph_index();
+  int32_t upper_bound = b->last_glyph_index();
+  int32_t last_gid = -1;
+  BitmapGlyphInfoMap::const_iterator i = loca.lower_bound(lower_bound);
+  BitmapGlyphInfoMap::const_iterator end = loca.end();
+  if (i != end) {
+    last_gid = i->first;
+    builder4->set_first_glyph_index(last_gid);
+    builder4->set_image_format(b->image_format());
+    builder4->set_image_data_offset(*image_data_offset);
+  }
+  for (; i != end; i++) {
+    int32_t gid = i->first;
+    if (gid > upper_bound) {
+      break;
+    }
+    offset_pairs.push_back(
+        IndexSubTableFormat4::CodeOffsetPairBuilder(gid, offset));
+    offset += i->second->length();
+    last_gid = gid;
+  }
+  offset_pairs.push_back(
+      IndexSubTableFormat4::CodeOffsetPairBuilder(-1, offset));
+  builder4->set_last_glyph_index(last_gid);
+  *image_data_offset += offset;
+  builder4->SetOffsetArray(offset_pairs);
+
+  return builder4.Detach();
+}
+
+CALLER_ATTACH IndexSubTable::Builder*
+ConstructIndexFormat5(IndexSubTable::Builder* b, const BitmapGlyphInfoMap& loca,
+                      int32_t* image_data_offset) {
+  IndexSubTableFormat5BuilderPtr new_builder;
+  new_builder.Attach(IndexSubTableFormat5::Builder::CreateBuilder());
+
+  // Copy BigMetrics
+  int32_t image_size = 0;
+  if (b->index_format() == IndexSubTable::Format::FORMAT_2) {
+    IndexSubTableFormat2BuilderPtr builder2 =
+      down_cast<IndexSubTableFormat2::Builder*>(b);
+    CopyBigGlyphMetrics(builder2->BigMetrics(), new_builder->BigMetrics());
+    image_size = builder2->ImageSize();
+  } else {
+    IndexSubTableFormat5BuilderPtr builder5 =
+      down_cast<IndexSubTableFormat5::Builder*>(b);
+    BigGlyphMetricsBuilderPtr metrics_builder;
+    CopyBigGlyphMetrics(builder5->BigMetrics(), new_builder->BigMetrics());
+    image_size = builder5->ImageSize();
+  }
+
+  IntegerList* glyph_array = new_builder->GlyphArray();
+  size_t offset = 0;
+  int32_t lower_bound = b->first_glyph_index();
+  int32_t upper_bound = b->last_glyph_index();
+  int32_t last_gid = -1;
+  BitmapGlyphInfoMap::const_iterator i = loca.lower_bound(lower_bound);
+  BitmapGlyphInfoMap::const_iterator end = loca.end();
+  if (i != end) {
+    last_gid = i->first;
+    new_builder->set_first_glyph_index(last_gid);
+    new_builder->set_image_format(b->image_format());
+    new_builder->set_image_data_offset(*image_data_offset);
+    new_builder->SetImageSize(image_size);
+  }
+  for (; i != end; i++) {
+    int32_t gid = i->first;
+    if (gid > upper_bound) {
+      break;
+    }
+    glyph_array->push_back(gid);
+    offset += i->second->length();
+    last_gid = gid;
+  }
+  new_builder->set_last_glyph_index(last_gid);
+  *image_data_offset += offset;
+  return new_builder.Detach();
+}
+
+CALLER_ATTACH IndexSubTable::Builder*
+SubsetIndexSubTable(IndexSubTable::Builder* builder,
+                    const BitmapGlyphInfoMap& loca,
+                    int32_t* image_data_offset) {
+  switch (builder->index_format()) {
+    case IndexSubTable::Format::FORMAT_1:
+    case IndexSubTable::Format::FORMAT_3:
+    case IndexSubTable::Format::FORMAT_4:
+      return ConstructIndexFormat4(builder, loca, image_data_offset);
+    case IndexSubTable::Format::FORMAT_2:
+    case IndexSubTable::Format::FORMAT_5:
+      return ConstructIndexFormat5(builder, loca, image_data_offset);
+    default:
+      assert(false);
+      break;
+  }
+  return NULL;
+}
+
+}
+
+namespace sfntly {
+
+// Not thread-safe, caller to ensure object life-time.
+void SubsetEBLC(EblcTable::Builder* eblc, const BitmapLocaList& new_loca) {
+  BitmapSizeTableBuilderList* size_builders = eblc->BitmapSizeBuilders();
+  if (size_builders == NULL) {
+    return;
+  }
+
+  int32_t image_data_offset = EbdtTable::Offset::kHeaderLength;
+  for (size_t strike = 0; strike < size_builders->size(); ++strike) {
+    IndexSubTableBuilderList* index_builders =
+        (*size_builders)[strike]->IndexSubTableBuilders();
+    for (size_t index = 0; index < index_builders->size(); ++index) {
+      IndexSubTable::Builder* new_builder_raw =
+          SubsetIndexSubTable((*index_builders)[index], new_loca[strike],
+                              &image_data_offset);
+      if (NULL != new_builder_raw) {
+        (*index_builders)[index].Attach(new_builder_raw);
+      }
+    }
+  }
+}
+
+// EBLC structure (from stuartg)
+//  header
+//  bitmapSizeTable[]
+//    one per strike
+//    holds strike metrics - sbitLineMetrics
+//    holds info about indexSubTableArray
+//  indexSubTableArray[][]
+//    one per strike and then one per indexSubTable for that strike
+//    holds info about the indexSubTable
+//    the indexSubTable entries pointed to can be of different formats
+//  indexSubTable
+//    one per indexSubTableArray entry
+//    tells how to get the glyphs
+//    may hold the glyph metrics if they are uniform for all the glyphs in range
+// Please note that the structure can also be
+//  {indexSubTableArray[], indexSubTables[]}[]
+//  This way is also legal and in fact how Microsoft fonts are laid out.
+//
+// There is nothing that says that the indexSubTableArray entries and/or the
+// indexSubTable items need to be unique. They may be shared between strikes.
+//
+// EBDT structure:
+//  header
+//  glyphs
+//    amorphous blob of data
+//    different glyphs that are only able to be figured out from the EBLC table
+//    may hold metrics - depends on the EBLC entry that pointed to them
+
+// Subsetting EBLC table (from arthurhsu)
+//  Most pages use only a fraction (hundreds or less) glyphs out of a given font
+//  (which can have >20K glyphs for CJK).  It's safe to assume that the subset
+//  font will have sparse bitmap glyphs.  So we reconstruct the EBLC table as
+//  format 4 or 5 here.
+
+enum BuildersToRemove {
+  kRemoveNone,
+  kRemoveBDAT,
+  kRemoveBDATAndEBDT,
+  kRemoveEBDT
+};
+
+int SetupBitmapBuilders(Font* font, Font::Builder* font_builder,
+                        const IntegerSet& glyph_ids) {
+  if (!font || !font_builder) {
+    return false;
+  }
+
+  // Check if bitmap table exists.
+  EbdtTablePtr ebdt_table = down_cast<EbdtTable*>(font->GetTable(Tag::EBDT));
+  EblcTablePtr eblc_table = down_cast<EblcTable*>(font->GetTable(Tag::EBLC));
+  bool use_ebdt = (ebdt_table != NULL && eblc_table != NULL);
+  if (!use_ebdt) {
+    ebdt_table = down_cast<EbdtTable*>(font->GetTable(Tag::bdat));
+    eblc_table = down_cast<EblcTable*>(font->GetTable(Tag::bloc));
+    if (ebdt_table == NULL || eblc_table == NULL) {
+      return kRemoveNone;
+    }
+  }
+
+  // If the bitmap table's size is too small, skip subsetting.
+  if (ebdt_table->DataLength() + eblc_table->DataLength() <
+      BITMAP_SIZE_THRESHOLD) {
+    return use_ebdt ? kRemoveBDAT : kRemoveNone;
+  }
+
+  // Get the builders.
+  EbdtTableBuilderPtr ebdt_table_builder = down_cast<EbdtTable::Builder*>(
+      font_builder->NewTableBuilder(use_ebdt ? Tag::EBDT : Tag::bdat,
+                                    ebdt_table->ReadFontData()));
+  EblcTableBuilderPtr eblc_table_builder = down_cast<EblcTable::Builder*>(
+      font_builder->NewTableBuilder(use_ebdt ? Tag::EBLC : Tag::bloc,
+                                    eblc_table->ReadFontData()));
+  if (ebdt_table_builder == NULL || eblc_table_builder == NULL) {
+    // Out of memory.
+    return use_ebdt ? kRemoveBDAT : kRemoveNone;
+  }
+
+  if (!InitializeBitmapBuilder(ebdt_table_builder, eblc_table_builder,
+                               glyph_ids)) {
+    // Bitmap tables do not cover the glyphs in our subset.
+    font_builder->RemoveTableBuilder(use_ebdt ? Tag::EBLC : Tag::bloc);
+    font_builder->RemoveTableBuilder(use_ebdt ? Tag::EBDT : Tag::bdat);
+    return use_ebdt ? kRemoveBDATAndEBDT : kRemoveEBDT;
+  }
+
+  BitmapLocaList new_loca;
+  ebdt_table_builder->GenerateLocaList(&new_loca);
+  SubsetEBLC(eblc_table_builder, new_loca);
+
+  return use_ebdt ? kRemoveBDAT : kRemoveNone;
+}
+
+SubsetterImpl::SubsetterImpl() {
+}
+
+SubsetterImpl::~SubsetterImpl() {
+}
+
+bool SubsetterImpl::LoadFont(const char* font_name,
+                             const unsigned char* original_font,
+                             size_t font_size) {
+  MemoryInputStream mis;
+  mis.Attach(original_font, font_size);
+  if (factory_ == NULL) {
+    factory_.Attach(FontFactory::GetInstance());
+  }
+
+  FontArray font_array;
+  factory_->LoadFonts(&mis, &font_array);
+  font_ = FindFont(font_name, font_array);
+  if (font_ == NULL) {
+    return false;
+  }
+
+  return true;
+}
+
+int SubsetterImpl::SubsetFont(const unsigned int* glyph_ids,
+                              size_t glyph_count,
+                              unsigned char** output_buffer) {
+  if (factory_ == NULL || font_ == NULL) {
+    return -1;
+  }
+
+  // Find glyf and loca table.
+  GlyphTablePtr glyph_table =
+      down_cast<GlyphTable*>(font_->GetTable(Tag::glyf));
+  LocaTablePtr loca_table = down_cast<LocaTable*>(font_->GetTable(Tag::loca));
+  if (glyph_table == NULL || loca_table == NULL) {
+    // We are not able to subset the font.
+    return 0;
+  }
+
+  IntegerSet glyph_id_processed;
+  if (!ResolveCompositeGlyphs(glyph_table, loca_table,
+                              glyph_ids, glyph_count, &glyph_id_processed) ||
+      glyph_id_processed.empty()) {
+    return 0;
+  }
+
+  FontPtr new_font;
+  new_font.Attach(Subset(glyph_id_processed, glyph_table, loca_table));
+  if (new_font == NULL) {
+    return 0;
+  }
+
+  MemoryOutputStream output_stream;
+  factory_->SerializeFont(new_font, &output_stream);
+  int length = static_cast<int>(output_stream.Size());
+  if (length > 0) {
+    *output_buffer = new unsigned char[length];
+    memcpy(*output_buffer, output_stream.Get(), length);
+  }
+
+  return length;
+}
+
+// Long comments regarding TTF tables and PDF (from stuartg)
+//
+// According to PDF spec 1.4 (section 5.8), the following tables must be
+// present:
+//  head, hhea, loca, maxp, cvt, prep, glyf, hmtx, fpgm
+//  cmap if font is used with a simple font dict and not a CIDFont dict
+//
+// Other tables we need to keep for PDF rendering to support zoom in/out:
+//  bdat, bloc, ebdt, eblc, ebsc, gasp
+//
+// Special table:
+//  CFF - if you have this table then you shouldn't have a glyf table and this
+//        is the table with all the glyphs.  Shall skip subsetting completely
+//        since sfntly is not capable of subsetting it for now.
+//  post - extra info here for printing on PostScript printers but maybe not
+//         enough to outweigh the space taken by the names
+//
+// Tables to break apart:
+//  name - could throw away all but one language and one platform strings/ might
+//         throw away some of the name entries
+//  cmap - could strip out non-needed cmap subtables
+//       - format 4 subtable can be subsetted as well using sfntly
+//
+// Graphite tables:
+//  silf, glat, gloc, feat - should be okay to strip out
+//
+// Tables that can be discarded:
+//  OS/2 - everything here is for layout and description of the font that is
+//         elsewhere (some in the PDF objects)
+//  BASE, GDEF, GSUB, GPOS, JSTF - all used for layout
+//  kern - old style layout
+//  DSIG - this will be invalid after subsetting
+//  hdmx - layout
+//  PCLT - metadata that's not needed
+//  vmtx - layout
+//  vhea - layout
+//  VDMX
+//  VORG - not used by TT/OT - used by CFF
+//  hsty - would be surprised to see one of these - used on the Newton
+//  AAT tables - mort, morx, feat, acnt, bsin, just, lcar, fdsc, fmtx, prop,
+//               Zapf, opbd, trak, fvar, gvar, avar, cvar
+//             - these are all layout tables and once layout happens are not
+//               needed anymore
+//  LTSH - layout
+
+CALLER_ATTACH
+Font* SubsetterImpl::Subset(const IntegerSet& glyph_ids, GlyphTable* glyf,
+                            LocaTable* loca) {
+  // The const is initialized here to workaround VC bug of rendering all Tag::*
+  // as 0.  These tags represents the TTF tables that we will embed in subset
+  // font.
+  const int32_t TABLES_IN_SUBSET[] = {
+    Tag::head, Tag::hhea, Tag::loca, Tag::maxp, Tag::cvt,
+    Tag::prep, Tag::glyf, Tag::hmtx, Tag::fpgm, Tag::EBDT,
+    Tag::EBLC, Tag::EBSC, Tag::bdat, Tag::bloc, Tag::bhed,
+    Tag::cmap,  // Keep here for future tagged PDF development.
+    Tag::name,  // Keep here due to legal concerns: copyright info inside.
+  };
+
+  // Setup font builders we need.
+  FontBuilderPtr font_builder;
+  font_builder.Attach(factory_->NewFontBuilder());
+  IntegerSet remove_tags;
+
+  if (SetupGlyfBuilders(font_builder, glyf, loca, glyph_ids)) {
+    remove_tags.insert(Tag::glyf);
+    remove_tags.insert(Tag::loca);
+  }
+
+  // For old Apple bitmap fonts, they have only bdats and bhed is identical
+  // to head.  As a result, we can't remove bdat tables for those fonts.
+  int setup_result = SetupBitmapBuilders(font_, font_builder, glyph_ids);
+  if (setup_result == kRemoveBDATAndEBDT || setup_result == kRemoveEBDT) {
+    remove_tags.insert(Tag::EBDT);
+    remove_tags.insert(Tag::EBLC);
+    remove_tags.insert(Tag::EBSC);
+  }
+
+  if (setup_result == kRemoveBDAT || setup_result == kRemoveBDATAndEBDT) {
+    remove_tags.insert(Tag::bdat);
+    remove_tags.insert(Tag::bloc);
+    remove_tags.insert(Tag::bhed);
+  }
+
+  IntegerSet allowed_tags;
+  for (size_t i = 0; i < sizeof(TABLES_IN_SUBSET) / sizeof(int32_t); ++i) {
+    allowed_tags.insert(TABLES_IN_SUBSET[i]);
+  }
+
+  IntegerSet result;
+  std::set_difference(allowed_tags.begin(), allowed_tags.end(),
+                      remove_tags.begin(), remove_tags.end(),
+                      std::inserter(result, result.end()));
+  allowed_tags = result;
+
+  // Setup remaining builders.
+  for (IntegerSet::iterator i = allowed_tags.begin(), e = allowed_tags.end();
+                            i != e; ++i) {
+    Table* table = font_->GetTable(*i);
+    if (table) {
+      font_builder->NewTableBuilder(*i, table->ReadFontData());
+    }
+  }
+
+  return font_builder->Build();
+}
+
+}  // namespace sfntly
diff --git a/sample/chromium/subsetter_impl.h b/sample/chromium/subsetter_impl.h
new file mode 100644
index 0000000..ffbf408
--- /dev/null
+++ b/sample/chromium/subsetter_impl.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+// File is originally from Chromium third_party/sfntly/src/subsetter.
+// Use as test case in sfntly so that problems can be caught in upstream early.
+
+#ifndef SFNTLY_CPP_SRC_TEST_SUBSETTER_IMPL_H_
+#define SFNTLY_CPP_SRC_TEST_SUBSETTER_IMPL_H_
+
+#include "sfntly/font.h"
+#include "sfntly/font_factory.h"
+#include "sfntly/table/truetype/glyph_table.h"
+#include "sfntly/table/truetype/loca_table.h"
+#include "sfntly/tag.h"
+
+namespace sfntly {
+
+// Smart pointer usage in sfntly:
+//
+// sfntly carries a smart pointer implementation like COM.  Ref-countable object
+// type inherits from RefCounted<>, which have AddRef and Release just like
+// IUnknown (but no QueryInterface).  Use a Ptr<> based smart pointer to hold
+// the object so that the object ref count is handled correctly.
+//
+// class Foo : public RefCounted<Foo> {
+//  public:
+//   static Foo* CreateInstance() {
+//     Ptr<Foo> obj = new Foo();  // ref count = 1
+//     return obj.detach();
+//   }
+// };
+// typedef Ptr<Foo> FooPtr;  // common short-hand notation
+// FooPtr obj;
+// obj.attach(Foo::CreatedInstance());  // ref count = 1
+// {
+//   FooPtr obj2 = obj;  // ref count = 2
+// }  // ref count = 1, obj2 out of scope
+// obj.release();  // ref count = 0, object destroyed
+
+class SubsetterImpl {
+ public:
+  SubsetterImpl();
+  ~SubsetterImpl();
+
+  bool LoadFont(const char* font_name,
+                const unsigned char* original_font,
+                size_t font_size);
+  int SubsetFont(const unsigned int* glyph_ids,
+                 size_t glyph_count,
+                 unsigned char** output_buffer);
+
+ private:
+  CALLER_ATTACH Font* Subset(const IntegerSet& glyph_ids,
+                             GlyphTable* glyf, LocaTable* loca);
+
+  FontFactoryPtr factory_;
+  FontPtr font_;
+};
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_TEST_SUBSETTER_IMPL_H_
diff --git a/sample/subsetter/main.cc b/sample/subsetter/main.cc
new file mode 100644
index 0000000..19a3e0e
--- /dev/null
+++ b/sample/subsetter/main.cc
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#if _MSC_VER > 12
+  #define _CRTDBG_MAP_ALLOC
+  #include <stdlib.h>
+  #include <crtdbg.h>
+#endif
+
+#include "sample/subsetter/subset_util.h"
+
+int main(int argc, char** argv) {
+#ifdef _CRTDBG_MAP_ALLOC
+  _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
+#endif
+
+  if (argc < 3) {
+    printf("Usage: subsetter <font file> <output file>\n");
+    return 0;
+  }
+
+  sfntly::SubsetUtil subset_util;
+  subset_util.Subset(argv[1], argv[2]);
+
+#ifdef _CRTDBG_MAP_ALLOC
+  _CrtDumpMemoryLeaks();
+#endif
+
+  return 0;
+}
diff --git a/sample/subsetter/subset_util.cc b/sample/subsetter/subset_util.cc
new file mode 100644
index 0000000..f35eb25
--- /dev/null
+++ b/sample/subsetter/subset_util.cc
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+// Remove VC++ nag on fopen.
+#define _CRT_SECURE_NO_WARNINGS
+
+#include "sample/subsetter/subset_util.h"
+
+#include <stdio.h>
+
+#include <vector>
+#include <memory>
+
+#include "sfntly/font.h"
+#include "sfntly/data/memory_byte_array.h"
+#include "sfntly/port/memory_output_stream.h"
+#include "sfntly/port/type.h"
+#include "sfntly/tag.h"
+#include "sfntly/tools/subsetter/subsetter.h"
+
+namespace sfntly {
+
+SubsetUtil::SubsetUtil() {
+}
+
+SubsetUtil::~SubsetUtil() {
+}
+
+void SubsetUtil::Subset(const char *input_file_path,
+                        const char *output_file_path) {
+  UNREFERENCED_PARAMETER(output_file_path);
+  ByteVector input_buffer;
+  FILE* input_file = fopen(input_file_path, "rb");
+  if (input_file == NULL) {
+    fprintf(stderr, "file not found\n");
+    return;
+  }
+  fseek(input_file, 0, SEEK_END);
+  size_t file_size = ftell(input_file);
+  fseek(input_file, 0, SEEK_SET);
+  input_buffer.resize(file_size);
+  size_t bytes_read = fread(&(input_buffer[0]), 1, file_size, input_file);
+  UNREFERENCED_PARAMETER(bytes_read);
+  fclose(input_file);
+
+  FontFactoryPtr factory;
+  factory.Attach(FontFactory::GetInstance());
+
+  FontArray font_array;
+  factory->LoadFonts(&input_buffer, &font_array);
+  if (font_array.empty() || font_array[0] == NULL)
+    return;
+
+  IntegerList glyphs;
+  for (int32_t i = 0; i < 10; i++) {
+    glyphs.push_back(i);
+  }
+  glyphs.push_back(11);
+  glyphs.push_back(10);
+
+  Ptr<Subsetter> subsetter = new Subsetter(font_array[0], factory);
+  subsetter->SetGlyphs(&glyphs);
+  IntegerSet remove_tables;
+  remove_tables.insert(Tag::DSIG);
+  subsetter->SetRemoveTables(&remove_tables);
+
+  FontBuilderPtr font_builder;
+  font_builder.Attach(subsetter->Subset());
+
+  FontPtr new_font;
+  new_font.Attach(font_builder->Build());
+
+  // TODO(arthurhsu): glyph renumbering/Loca table
+  // TODO(arthurhsu): alter CMaps
+
+  MemoryOutputStream output_stream;
+  factory->SerializeFont(new_font, &output_stream);
+
+  FILE* output_file = fopen(output_file_path, "wb");
+  fwrite(output_stream.Get(), 1, output_stream.Size(), output_file);
+  fflush(output_file);
+  fclose(output_file);
+}
+
+}  // namespace sfntly
diff --git a/sample/subsetter/subset_util.h b/sample/subsetter/subset_util.h
new file mode 100644
index 0000000..5eb4fe4
--- /dev/null
+++ b/sample/subsetter/subset_util.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SAMPLE_SUBSETTER_SUBSET_UTIL_H_
+#define SFNTLY_CPP_SRC_SAMPLE_SUBSETTER_SUBSET_UTIL_H_
+
+namespace sfntly {
+
+class SubsetUtil {
+ public:
+  SubsetUtil();
+  virtual ~SubsetUtil();
+
+  void Subset(const char* input_file_path, const char* output_file_path);
+};
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SAMPLE_SUBSETTER_SUBSET_UTIL_H_
diff --git a/sample/subtly/character_predicate.cc b/sample/subtly/character_predicate.cc
new file mode 100644
index 0000000..b9c6cc7
--- /dev/null
+++ b/sample/subtly/character_predicate.cc
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/port/refcount.h"
+#include "subtly/character_predicate.h"
+
+namespace subtly {
+using namespace sfntly;
+
+// AcceptRange predicate
+AcceptRange::AcceptRange(int32_t start, int32_t end)
+    : start_(start),
+      end_(end) {
+}
+
+AcceptRange::~AcceptRange() {}
+
+bool AcceptRange::operator()(int32_t character) const {
+  return start_ <= character && character <= end_;
+}
+
+// AcceptSet predicate
+AcceptSet::AcceptSet(IntegerSet* characters)
+    : characters_(characters) {
+}
+
+AcceptSet::~AcceptSet() {
+  delete characters_;
+}
+
+bool AcceptSet::operator()(int32_t character) const {
+  return characters_->find(character) != characters_->end();
+}
+
+// AcceptAll predicate
+bool AcceptAll::operator()(int32_t character) const {
+  UNREFERENCED_PARAMETER(character);
+  return true;
+}
+}
diff --git a/sample/subtly/character_predicate.h b/sample/subtly/character_predicate.h
new file mode 100644
index 0000000..a6e3ea3
--- /dev/null
+++ b/sample/subtly/character_predicate.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_CHARACTER_PREDICATE_H_
+#define TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_CHARACTER_PREDICATE_H_
+
+#include "sfntly/port/refcount.h"
+#include "sfntly/port/type.h"
+
+namespace subtly {
+class CharacterPredicate : virtual public sfntly::RefCount {
+ public:
+  CharacterPredicate() {}
+  virtual ~CharacterPredicate() {}
+  virtual bool operator()(int32_t character) const = 0;
+};
+
+// All characters except for those between [start, end] are rejected
+class AcceptRange : public CharacterPredicate,
+                    public sfntly::RefCounted<AcceptRange> {
+ public:
+  AcceptRange(int32_t start, int32_t end);
+  ~AcceptRange();
+  virtual bool operator()(int32_t character) const;
+
+ private:
+  int32_t start_;
+  int32_t end_;
+};
+
+// All characters in IntegerSet
+// The set is OWNED by the predicate! Do not modify it.
+// It will be freed when the predicate is destroyed.
+class AcceptSet : public CharacterPredicate,
+                  public sfntly::RefCounted<AcceptSet> {
+ public:
+  explicit AcceptSet(sfntly::IntegerSet* characters);
+  ~AcceptSet();
+  virtual bool operator()(int32_t character) const;
+
+ private:
+  sfntly::IntegerSet* characters_;
+};
+
+// All characters
+class AcceptAll : public CharacterPredicate,
+                  public sfntly::RefCounted<AcceptAll> {
+ public:
+  AcceptAll() {}
+  ~AcceptAll() {}
+  virtual bool operator()(int32_t character) const;
+};
+}
+
+#endif  // TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_CHARACTER_PREDICATE_H_
diff --git a/sample/subtly/debug_main.cc b/sample/subtly/debug_main.cc
new file mode 100644
index 0000000..8324cde
--- /dev/null
+++ b/sample/subtly/debug_main.cc
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <map>
+#include <utility>
+
+#include "sfntly/font.h"
+#include "sfntly/table/core/cmap_table.h"
+#include "sfntly/tag.h"
+#include "subtly/stats.h"
+#include "subtly/subsetter.h"
+#include "subtly/utils.h"
+
+using namespace subtly;
+
+void PrintUsage(const char* program_name) {
+  fprintf(stdout, "Usage: %s <input_font_file>\n", program_name);
+}
+
+int main(int argc, const char** argv) {
+  const char* program_name = argv[0];
+  if (argc < 2) {
+    PrintUsage(program_name);
+    exit(1);
+  }
+
+  const char* input_font_path = argv[1];
+  const char* output_font_path = argv[2];
+  FontPtr font;
+  font.Attach(subtly::LoadFont(input_font_path));
+
+  int32_t original_size = TotalFontSize(font);
+  Ptr<Subsetter> subsetter = new Subsetter(font, NULL);
+  Ptr<Font> new_font;
+  new_font.Attach(subsetter->Subset());
+  if (!new_font) {
+    fprintf(stdout, "Cannot create subset.\n");
+    return 0;
+  }
+
+  subtly::SerializeFont(output_font_path, new_font);
+  subtly::PrintComparison(stdout, font, new_font);
+  int32_t new_size = TotalFontSize(new_font);
+  fprintf(stdout, "Went from %d to %d: %lf%% of original\n",
+          original_size, new_size,
+          static_cast<double>(new_size) / original_size * 100);
+  return 0;
+}
diff --git a/sample/subtly/font_assembler.cc b/sample/subtly/font_assembler.cc
new file mode 100644
index 0000000..2f7cd11
--- /dev/null
+++ b/sample/subtly/font_assembler.cc
@@ -0,0 +1,227 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "subtly/font_assembler.h"
+
+#include <stdio.h>
+
+#include <set>
+#include <map>
+
+#include "sfntly/tag.h"
+#include "sfntly/font.h"
+#include "sfntly/font_factory.h"
+#include "sfntly/table/core/cmap_table.h"
+#include "sfntly/table/truetype/loca_table.h"
+#include "sfntly/table/truetype/glyph_table.h"
+#include "sfntly/table/core/maximum_profile_table.h"
+#include "sfntly/port/type.h"
+#include "sfntly/port/refcount.h"
+#include "subtly/font_info.h"
+
+namespace subtly {
+using namespace sfntly;
+
+FontAssembler::FontAssembler(FontInfo* font_info,
+                             IntegerSet* table_blacklist)
+    : table_blacklist_(table_blacklist) {
+  font_info_ = font_info;
+  Initialize();
+}
+
+FontAssembler::FontAssembler(FontInfo* font_info)
+    : table_blacklist_(NULL) {
+  font_info_ = font_info;
+  Initialize();
+}
+
+void FontAssembler::Initialize() {
+  font_factory_.Attach(sfntly::FontFactory::GetInstance());
+  font_builder_.Attach(font_factory_->NewFontBuilder());
+}
+
+CALLER_ATTACH Font* FontAssembler::Assemble() {
+  // Assemble tables we can subset.
+  if (!AssembleCMapTable() || !AssembleGlyphAndLocaTables()) {
+    return NULL;
+  }
+  // For all other tables, either include them unmodified or don't at all.
+  const TableMap* common_table_map =
+      font_info_->GetTableMap(font_info_->fonts()->begin()->first);
+  for (TableMap::const_iterator it = common_table_map->begin(),
+           e = common_table_map->end(); it != e; ++it) {
+    if (table_blacklist_
+        && table_blacklist_->find(it->first) != table_blacklist_->end()) {
+      continue;
+    }
+    font_builder_->NewTableBuilder(it->first, it->second->ReadFontData());
+  }
+  return font_builder_->Build();
+}
+
+bool FontAssembler::AssembleCMapTable() {
+  // Creating the new CMapTable and the new format 4 CMap
+  Ptr<CMapTable::Builder> cmap_table_builder =
+      down_cast<CMapTable::Builder*>
+      (font_builder_->NewTableBuilder(Tag::cmap));
+  if (!cmap_table_builder)
+    return false;
+  Ptr<CMapTable::CMapFormat4::Builder> cmap_builder =
+      down_cast<CMapTable::CMapFormat4::Builder*>
+      (cmap_table_builder->NewCMapBuilder(CMapFormat::kFormat4,
+                                          CMapTable::WINDOWS_BMP));
+  if (!cmap_builder)
+    return false;
+  // Creating the segments and the glyph id array
+  CharacterMap* chars_to_glyph_ids = font_info_->chars_to_glyph_ids();
+  SegmentList* segment_list = new SegmentList;
+  IntegerList* glyph_id_array = new IntegerList;
+  int32_t last_chararacter = -2;
+  int32_t last_offset = 0;
+  Ptr<CMapTable::CMapFormat4::Builder::Segment> current_segment;
+
+  // For simplicity, we will have one segment per contiguous range.
+  // To test the algorithm, we've replaced the original CMap with the CMap
+  // generated by this code without removing any character.
+  // Tuffy.ttf: CMap went from 3146 to 3972 bytes (1.7% to 2.17% of file)
+  // AnonymousPro.ttf: CMap went from 1524 to 1900 bytes (0.96% to 1.2%)
+  for (CharacterMap::iterator it = chars_to_glyph_ids->begin(),
+           e = chars_to_glyph_ids->end(); it != e; ++it) {
+    int32_t character = it->first;
+    int32_t glyph_id = it->second.glyph_id();
+    if (character != last_chararacter + 1) {  // new segment
+      if (current_segment != NULL) {
+        current_segment->set_end_count(last_chararacter);
+        segment_list->push_back(current_segment);
+      }
+      // start_code = character
+      // end_code = -1 (unknown for now)
+      // id_delta = 0 (we don't use id_delta for this representation)
+      // id_range_offset = last_offset (offset into the glyph_id_array)
+      current_segment =
+          new CMapTable::CMapFormat4::Builder::
+          Segment(character, -1, 0, last_offset);
+    }
+    glyph_id_array->push_back(glyph_id);
+    last_offset += DataSize::kSHORT;
+    last_chararacter = character;
+  }
+  // The last segment is still open.
+  current_segment->set_end_count(last_chararacter);
+  segment_list->push_back(current_segment);
+  // Updating the id_range_offset for every segment.
+  for (int32_t i = 0, num_segs = segment_list->size(); i < num_segs; ++i) {
+    Ptr<CMapTable::CMapFormat4::Builder::Segment> segment = segment_list->at(i);
+    segment->set_id_range_offset(segment->id_range_offset()
+                                 + (num_segs - i + 1) * DataSize::kSHORT);
+  }
+  // Adding the final, required segment.
+  current_segment =
+      new CMapTable::CMapFormat4::Builder::Segment(0xffff, 0xffff, 1, 0);
+  segment_list->push_back(current_segment);
+  // Writing the segments and glyph id array to the CMap
+  cmap_builder->set_segments(segment_list);
+  cmap_builder->set_glyph_id_array(glyph_id_array);
+  delete segment_list;
+  delete glyph_id_array;
+  return true;
+}
+
+bool FontAssembler::AssembleGlyphAndLocaTables() {
+  Ptr<LocaTable::Builder> loca_table_builder =
+      down_cast<LocaTable::Builder*>
+      (font_builder_->NewTableBuilder(Tag::loca));
+  Ptr<GlyphTable::Builder> glyph_table_builder =
+      down_cast<GlyphTable::Builder*>
+      (font_builder_->NewTableBuilder(Tag::glyf));
+
+  GlyphIdSet* resolved_glyph_ids = font_info_->resolved_glyph_ids();
+  IntegerList loca_list;
+  // Basic sanity check: all LOCA tables are of the same size
+  // This is necessary but not suficient!
+  int32_t previous_size = -1;
+  for (FontIdMap::iterator it = font_info_->fonts()->begin();
+       it != font_info_->fonts()->end(); ++it) {
+    Ptr<LocaTable> loca_table =
+        down_cast<LocaTable*>(font_info_->GetTable(it->first, Tag::loca));
+    int32_t current_size = loca_table->header_length();
+    if (previous_size != -1 && current_size != previous_size) {
+      return false;
+    }
+    previous_size = current_size;
+  }
+
+  // Assuming all fonts referenced by the FontInfo are the subsets of the same
+  // font, their loca tables should all have the same sizes.
+  // We'll just get the size of the first font's LOCA table for simplicty.
+  Ptr<LocaTable> first_loca_table =
+    down_cast<LocaTable*>
+    (font_info_->GetTable(font_info_->fonts()->begin()->first, Tag::loca));
+  int32_t num_loca_glyphs = first_loca_table->num_glyphs();
+  loca_list.resize(num_loca_glyphs);
+  loca_list.push_back(0);
+  int32_t last_glyph_id = 0;
+  int32_t last_offset = 0;
+  GlyphTable::GlyphBuilderList* glyph_builders =
+      glyph_table_builder->GlyphBuilders();
+
+  for (GlyphIdSet::iterator it = resolved_glyph_ids->begin(),
+           e = resolved_glyph_ids->end(); it != e; ++it) {
+    // Get the glyph for this resolved_glyph_id.
+    int32_t resolved_glyph_id = it->glyph_id();
+    int32_t font_id = it->font_id();
+    // Get the LOCA table for the current glyph id.
+    Ptr<LocaTable> loca_table =
+        down_cast<LocaTable*>
+        (font_info_->GetTable(font_id, Tag::loca));
+    int32_t length = loca_table->GlyphLength(resolved_glyph_id);
+    int32_t offset = loca_table->GlyphOffset(resolved_glyph_id);
+
+    // Get the GLYF table for the current glyph id.
+    Ptr<GlyphTable> glyph_table =
+        down_cast<GlyphTable*>
+        (font_info_->GetTable(font_id, Tag::glyf));
+    GlyphPtr glyph;
+    glyph.Attach(glyph_table->GetGlyph(offset, length));
+
+    // The data reference by the glyph is copied into a new glyph and
+    // added to the glyph_builders belonging to the glyph_table_builder.
+    // When Build gets called, all the glyphs will be built.
+    Ptr<ReadableFontData> data = glyph->ReadFontData();
+    Ptr<WritableFontData> copy_data;
+    copy_data.Attach(WritableFontData::CreateWritableFontData(data->Length()));
+    data->CopyTo(copy_data);
+    GlyphBuilderPtr glyph_builder;
+    glyph_builder.Attach(glyph_table_builder->GlyphBuilder(copy_data));
+    glyph_builders->push_back(glyph_builder);
+
+    // If there are missing glyphs between the last glyph_id and the
+    // current resolved_glyph_id, since the LOCA table needs to have the same
+    // size, the offset is kept the same.
+    for (int32_t i = last_glyph_id + 1; i <= resolved_glyph_id; ++i)
+      loca_list[i] = last_offset;
+    last_offset += length;
+    loca_list[resolved_glyph_id + 1] = last_offset;
+    last_glyph_id = resolved_glyph_id + 1;
+  }
+  // If there are missing glyph ids, their loca entries must all point
+  // to the same offset as the last valid glyph id making them all zero length.
+  for (int32_t i = last_glyph_id + 1; i <= num_loca_glyphs; ++i)
+    loca_list[i] = last_offset;
+  loca_table_builder->SetLocaList(&loca_list);
+  return true;
+}
+}
diff --git a/sample/subtly/font_assembler.h b/sample/subtly/font_assembler.h
new file mode 100644
index 0000000..c53c21f
--- /dev/null
+++ b/sample/subtly/font_assembler.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_FONT_ASSEMBLER_H_
+#define TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_FONT_ASSEMBLER_H_
+
+#include <set>
+#include <map>
+
+#include "subtly/font_info.h"
+
+#include "sfntly/tag.h"
+#include "sfntly/font.h"
+#include "sfntly/port/type.h"
+#include "sfntly/port/refcount.h"
+#include "sfntly/table/core/cmap_table.h"
+#include "sfntly/table/truetype/glyph_table.h"
+#include "sfntly/table/truetype/loca_table.h"
+
+namespace subtly {
+// Assembles FontInfo into font builders.
+// Does not take ownership of data passed to it.
+class FontAssembler : public sfntly::RefCounted<FontAssembler> {
+ public:
+  // font_info is the FontInfo which will be used for the new font
+  // table_blacklist is used to decide which tables to exclude from the
+  // final font.
+  FontAssembler(FontInfo* font_info, sfntly::IntegerSet* table_blacklist);
+  explicit FontAssembler(FontInfo* font_info);
+  ~FontAssembler() { }
+
+  // Assemble a new font from the font info object.
+  virtual CALLER_ATTACH sfntly::Font* Assemble();
+
+  sfntly::IntegerSet* table_blacklist() const { return table_blacklist_; }
+  void set_table_blacklist(sfntly::IntegerSet* table_blacklist) {
+    table_blacklist_ = table_blacklist;
+  }
+
+ protected:
+  virtual bool AssembleCMapTable();
+  virtual bool AssembleGlyphAndLocaTables();
+
+  virtual void Initialize();
+
+ private:
+  sfntly::Ptr<FontInfo> font_info_;
+  sfntly::Ptr<sfntly::FontFactory> font_factory_;
+  sfntly::Ptr<sfntly::Font::Builder> font_builder_;
+  sfntly::IntegerSet* table_blacklist_;
+};
+}
+
+#endif  // TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_FONT_ASSEMBLER_H_
diff --git a/sample/subtly/font_info.cc b/sample/subtly/font_info.cc
new file mode 100644
index 0000000..6eb6a38
--- /dev/null
+++ b/sample/subtly/font_info.cc
@@ -0,0 +1,256 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "subtly/font_info.h"
+
+#include <stdio.h>
+
+#include <set>
+#include <map>
+
+#include "subtly/character_predicate.h"
+
+#include "sfntly/tag.h"
+#include "sfntly/font.h"
+#include "sfntly/font_factory.h"
+#include "sfntly/table/core/cmap_table.h"
+#include "sfntly/table/truetype/loca_table.h"
+#include "sfntly/table/truetype/glyph_table.h"
+#include "sfntly/table/core/maximum_profile_table.h"
+#include "sfntly/port/type.h"
+#include "sfntly/port/refcount.h"
+
+namespace subtly {
+using namespace sfntly;
+/******************************************************************************
+ * GlyphId class
+ ******************************************************************************/
+GlyphId::GlyphId(int32_t glyph_id, FontId font_id)
+    : glyph_id_(glyph_id),
+      font_id_(font_id) {
+}
+
+bool GlyphId::operator==(const GlyphId& other) const {
+  return glyph_id_ == other.glyph_id();
+}
+
+bool GlyphId::operator<(const GlyphId& other) const {
+  return glyph_id_ < other.glyph_id();
+}
+
+/******************************************************************************
+ * FontInfo class
+ ******************************************************************************/
+FontInfo::FontInfo()
+    : chars_to_glyph_ids_(new CharacterMap),
+      resolved_glyph_ids_(new GlyphIdSet),
+      fonts_(new FontIdMap) {
+}
+
+FontInfo::FontInfo(CharacterMap* chars_to_glyph_ids,
+                   GlyphIdSet* resolved_glyph_ids,
+                   FontIdMap* fonts) {
+  chars_to_glyph_ids_ = new CharacterMap(chars_to_glyph_ids->begin(),
+                                         chars_to_glyph_ids->end());
+  resolved_glyph_ids_ = new GlyphIdSet(resolved_glyph_ids->begin(),
+                                       resolved_glyph_ids->end());
+  fonts_ = new FontIdMap(fonts->begin(), fonts->end());
+}
+
+FontInfo::~FontInfo() {
+  delete chars_to_glyph_ids_;
+  delete resolved_glyph_ids_;
+  delete fonts_;
+}
+
+FontDataTable* FontInfo::GetTable(FontId font_id, int32_t tag) {
+  if (!fonts_)
+    return NULL;
+  FontIdMap::iterator it = fonts_->find(font_id);
+  if (it == fonts_->end())
+    return NULL;
+  return it->second->GetTable(tag);
+}
+
+const TableMap* FontInfo::GetTableMap(FontId font_id) {
+  if (!fonts_)
+    return NULL;
+  FontIdMap::iterator it = fonts_->find(font_id);
+  if (it == fonts_->end())
+    return NULL;
+  return it->second->GetTableMap();
+}
+
+void FontInfo::set_chars_to_glyph_ids(CharacterMap* chars_to_glyph_ids) {
+  *chars_to_glyph_ids_ = *chars_to_glyph_ids;
+}
+
+void FontInfo::set_resolved_glyph_ids(GlyphIdSet* resolved_glyph_ids) {
+  *resolved_glyph_ids_ = *resolved_glyph_ids;
+}
+
+void FontInfo::set_fonts(FontIdMap* fonts) {
+  *fonts_ = *fonts;
+}
+
+/******************************************************************************
+ * FontSourcedInfoBuilder class
+ ******************************************************************************/
+FontSourcedInfoBuilder::FontSourcedInfoBuilder(Font* font, FontId font_id)
+    : font_(font),
+      font_id_(font_id),
+      predicate_(NULL) {
+  Initialize();
+}
+
+FontSourcedInfoBuilder::FontSourcedInfoBuilder(Font* font,
+                                               FontId font_id,
+                                               CharacterPredicate* predicate)
+    : font_(font),
+      font_id_(font_id),
+      predicate_(predicate) {
+  Initialize();
+}
+
+void FontSourcedInfoBuilder::Initialize() {
+  Ptr<CMapTable> cmap_table = down_cast<CMapTable*>(font_->GetTable(Tag::cmap));
+  // We prefer Windows BMP format 4 cmaps.
+  cmap_.Attach(cmap_table->GetCMap(CMapTable::WINDOWS_BMP));
+  // But if none is found,
+  if (!cmap_) {
+    return;
+  }
+  loca_table_ = down_cast<LocaTable*>(font_->GetTable(Tag::loca));
+  glyph_table_ = down_cast<GlyphTable*>(font_->GetTable(Tag::glyf));
+}
+
+CALLER_ATTACH FontInfo* FontSourcedInfoBuilder::GetFontInfo() {
+  CharacterMap* chars_to_glyph_ids = new CharacterMap;
+  bool success = GetCharacterMap(chars_to_glyph_ids);
+  if (!success) {
+    delete chars_to_glyph_ids;
+#if defined (SUBTLY_DEBUG)
+    fprintf(stderr, "Error creating character map.\n");
+#endif
+    return NULL;
+  }
+  GlyphIdSet* resolved_glyph_ids = new GlyphIdSet;
+  success = ResolveCompositeGlyphs(chars_to_glyph_ids, resolved_glyph_ids);
+  if (!success) {
+    delete chars_to_glyph_ids;
+    delete resolved_glyph_ids;
+#if defined (SUBTLY_DEBUG)
+    fprintf(stderr, "Error resolving composite glyphs.\n");
+#endif
+    return NULL;
+  }
+  Ptr<FontInfo> font_info = new FontInfo;
+  font_info->set_chars_to_glyph_ids(chars_to_glyph_ids);
+  font_info->set_resolved_glyph_ids(resolved_glyph_ids);
+  FontIdMap* font_id_map = new FontIdMap;
+  font_id_map->insert(std::make_pair(font_id_, font_));
+  font_info->set_fonts(font_id_map);
+  delete chars_to_glyph_ids;
+  delete resolved_glyph_ids;
+  delete font_id_map;
+  return font_info.Detach();
+}
+
+bool FontSourcedInfoBuilder::GetCharacterMap(CharacterMap* chars_to_glyph_ids) {
+  if (!cmap_ || !chars_to_glyph_ids)
+    return false;
+  chars_to_glyph_ids->clear();
+  CMapTable::CMap::CharacterIterator* character_iterator = cmap_->Iterator();
+  if (!character_iterator)
+    return false;
+  while (character_iterator->HasNext()) {
+    int32_t character = character_iterator->Next();
+    if (!predicate_ || (*predicate_)(character)) {
+      chars_to_glyph_ids->insert
+          (std::make_pair(character,
+                          GlyphId(cmap_->GlyphId(character), font_id_)));
+    }
+  }
+  delete character_iterator;
+  return true;
+}
+
+bool
+FontSourcedInfoBuilder::ResolveCompositeGlyphs(CharacterMap* chars_to_glyph_ids,
+                                               GlyphIdSet* resolved_glyph_ids) {
+  if (!chars_to_glyph_ids || !resolved_glyph_ids)
+    return false;
+  resolved_glyph_ids->clear();
+  resolved_glyph_ids->insert(GlyphId(0, font_id_));
+  IntegerSet* unresolved_glyph_ids = new IntegerSet;
+  // Since composite glyph elements might themselves be composite, we would need
+  // to recursively resolve the elements too. To avoid the recursion we
+  // create two sets, |unresolved_glyph_ids| for the unresolved glyphs,
+  // initially containing all the ids and |resolved_glyph_ids|, initially empty.
+  // We'll remove glyph ids from |unresolved_glyph_ids| until it is empty and,
+  // if the glyph is composite, add its elements to the unresolved set.
+  for (CharacterMap::iterator it = chars_to_glyph_ids->begin(),
+           e = chars_to_glyph_ids->end(); it != e; ++it) {
+    unresolved_glyph_ids->insert(it->second.glyph_id());
+  }
+  // As long as there are unresolved glyph ids.
+  while (!unresolved_glyph_ids->empty()) {
+    // Get the corresponding glyph.
+    int32_t glyph_id = *(unresolved_glyph_ids->begin());
+    unresolved_glyph_ids->erase(unresolved_glyph_ids->begin());
+    if (glyph_id < 0 || glyph_id > loca_table_->num_glyphs()) {
+#if defined (SUBTLY_DEBUG)
+      fprintf(stderr, "%d larger than %d or smaller than 0\n", glyph_id,
+              loca_table_->num_glyphs());
+#endif
+      continue;
+    }
+    int32_t length = loca_table_->GlyphLength(glyph_id);
+    if (length == 0) {
+#if defined (SUBTLY_DEBUG)
+      fprintf(stderr, "Zero length glyph %d\n", glyph_id);
+#endif
+      continue;
+    }
+    int32_t offset = loca_table_->GlyphOffset(glyph_id);
+    GlyphPtr glyph;
+    glyph.Attach(glyph_table_->GetGlyph(offset, length));
+    if (glyph == NULL) {
+#if defined (SUBTLY_DEBUG)
+      fprintf(stderr, "GetGlyph returned NULL for %d\n", glyph_id);
+#endif
+      continue;
+    }
+    // Mark the glyph as resolved.
+    resolved_glyph_ids->insert(GlyphId(glyph_id, font_id_));
+    // If it is composite, add all its components to the unresolved glyph set.
+    if (glyph->GlyphType() == GlyphType::kComposite) {
+      Ptr<GlyphTable::CompositeGlyph> composite_glyph =
+          down_cast<GlyphTable::CompositeGlyph*>(glyph.p_);
+      int32_t num_glyphs = composite_glyph->NumGlyphs();
+      for (int32_t i = 0; i < num_glyphs; ++i) {
+        int32_t glyph_id = composite_glyph->GlyphIndex(i);
+        if (resolved_glyph_ids->find(GlyphId(glyph_id, -1))
+            == resolved_glyph_ids->end()) {
+          unresolved_glyph_ids->insert(glyph_id);
+        }
+      }
+    }
+  }
+  delete unresolved_glyph_ids;
+  return true;
+}
+}
diff --git a/sample/subtly/font_info.h b/sample/subtly/font_info.h
new file mode 100644
index 0000000..6f42d73
--- /dev/null
+++ b/sample/subtly/font_info.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_FONT_INFO_H_
+#define TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_FONT_INFO_H_
+
+#include <map>
+#include <set>
+
+#include "sfntly/font.h"
+#include "sfntly/port/type.h"
+#include "sfntly/port/refcount.h"
+#include "sfntly/table/core/cmap_table.h"
+#include "sfntly/table/truetype/glyph_table.h"
+#include "sfntly/table/truetype/loca_table.h"
+
+namespace subtly {
+class CharacterPredicate;
+
+typedef int32_t FontId;
+typedef std::map<FontId, sfntly::Ptr<sfntly::Font> > FontIdMap;
+
+// Glyph id pair that contains the loca table glyph id as well as the
+// font id that has the glyph table this glyph belongs to.
+class GlyphId {
+ public:
+  GlyphId(int32_t glyph_id, FontId font_id);
+  ~GlyphId() {}
+
+  bool operator==(const GlyphId& other) const;
+  bool operator<(const GlyphId& other) const;
+
+  int32_t glyph_id() const { return glyph_id_; }
+  void set_glyph_id(const int32_t glyph_id) { glyph_id_ = glyph_id; }
+  FontId font_id() const { return font_id_; }
+  void set_font_id(const FontId font_id) { font_id_ = font_id; }
+
+ private:
+  int32_t glyph_id_;
+  FontId font_id_;
+};
+
+typedef std::map<int32_t, GlyphId> CharacterMap;
+typedef std::set<GlyphId> GlyphIdSet;
+
+// Font information used for FontAssembler in the construction of a new font.
+// Will make copies of character map, glyph id set and font id map.
+class FontInfo : public sfntly::RefCounted<FontInfo> {
+ public:
+  // Empty FontInfo object.
+  FontInfo();
+  // chars_to_glyph_ids maps characters to GlyphIds for CMap construction
+  // resolved_glyph_ids defines GlyphIds which should be in the final font
+  // fonts is a map of font ids to fonts to reference any needed table
+  FontInfo(CharacterMap* chars_to_glyph_ids,
+           GlyphIdSet* resolved_glyph_ids,
+           FontIdMap* fonts);
+  virtual ~FontInfo();
+
+  // Gets the table with the specified tag from the font corresponding to
+  // font_id or NULL if there is no such font/table.
+  // font_id is the id of the font that contains the table
+  // tag identifies the table to be obtained
+  virtual sfntly::FontDataTable* GetTable(FontId font_id, int32_t tag);
+  // Gets the table map of the font whose id is font_id
+  virtual const sfntly::TableMap* GetTableMap(FontId);
+
+  CharacterMap* chars_to_glyph_ids() const { return chars_to_glyph_ids_; }
+  // Takes ownership of the chars_to_glyph_ids CharacterMap.
+  void set_chars_to_glyph_ids(CharacterMap* chars_to_glyph_ids);
+  GlyphIdSet* resolved_glyph_ids() const { return resolved_glyph_ids_; }
+  // Takes ownership of the glyph_ids GlyphIdSet.
+  void set_resolved_glyph_ids(GlyphIdSet* glyph_ids);
+  FontIdMap* fonts() const { return fonts_; }
+  // Takes ownership of the fonts FontIdMap.
+  void set_fonts(FontIdMap* fonts);
+
+ private:
+  CharacterMap* chars_to_glyph_ids_;
+  GlyphIdSet* resolved_glyph_ids_;
+  FontIdMap* fonts_;
+};
+
+// FontSourcedInfoBuilder is used to create a FontInfo object from a Font
+// optionally specifying a CharacterPredicate to filter out some of
+// the font's characters.
+// It does not take ownership or copy the values its constructor receives.
+class FontSourcedInfoBuilder :
+      public sfntly::RefCounted<FontSourcedInfoBuilder> {
+ public:
+  FontSourcedInfoBuilder(sfntly::Font* font, FontId font_id);
+  FontSourcedInfoBuilder(sfntly::Font* font,
+                         FontId font_id,
+                         CharacterPredicate* predicate);
+  virtual ~FontSourcedInfoBuilder() { }
+
+  virtual CALLER_ATTACH FontInfo* GetFontInfo();
+
+ protected:
+  bool GetCharacterMap(CharacterMap* chars_to_glyph_ids);
+  bool ResolveCompositeGlyphs(CharacterMap* chars_to_glyph_ids,
+                              GlyphIdSet* resolved_glyph_ids);
+  void Initialize();
+
+ private:
+  sfntly::Ptr<sfntly::Font> font_;
+  FontId font_id_;
+  CharacterPredicate* predicate_;
+
+  sfntly::Ptr<sfntly::CMapTable::CMap> cmap_;
+  sfntly::Ptr<sfntly::LocaTable> loca_table_;
+  sfntly::Ptr<sfntly::GlyphTable> glyph_table_;
+};
+}
+#endif  // TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_FONT_INFO_H_
diff --git a/sample/subtly/merger.cc b/sample/subtly/merger.cc
new file mode 100644
index 0000000..7875c2d
--- /dev/null
+++ b/sample/subtly/merger.cc
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "subtly/merger.h"
+
+#include <stdio.h>
+
+#include "sfntly/font.h"
+#include "sfntly/font_factory.h"
+#include "subtly/character_predicate.h"
+#include "subtly/font_assembler.h"
+#include "subtly/font_info.h"
+#include "subtly/utils.h"
+
+namespace subtly {
+using namespace sfntly;
+
+/******************************************************************************
+ * Merger class
+ ******************************************************************************/
+Merger::Merger(FontArray* fonts) {
+  if (!fonts) {
+    return;
+  }
+  int32_t num_fonts = fonts->size();
+  for (int32_t i = 0; i < num_fonts; ++i) {
+    fonts_.insert(std::make_pair(i, fonts->at(i)));
+  }
+}
+
+CALLER_ATTACH Font* Merger::Merge() {
+  Ptr<FontInfo> merged_info;
+  merged_info.Attach(MergeFontInfos());
+  if (!merged_info) {
+#if defined (SUBTLY_DEBUG)
+    fprintf(stderr, "Could not create merged font info\n");
+#endif
+    return NULL;
+  }
+  Ptr<FontAssembler> font_assembler = new FontAssembler(merged_info);
+  return font_assembler->Assemble();
+}
+
+CALLER_ATTACH FontInfo* Merger::MergeFontInfos() {
+  Ptr<FontInfo> font_info = new FontInfo;
+  font_info->set_fonts(&fonts_);
+  for (FontIdMap::iterator it = fonts_.begin(),
+           e = fonts_.end(); it != e; ++it) {
+    Ptr<FontSourcedInfoBuilder> info_builder =
+        new FontSourcedInfoBuilder(it->second, it->first, NULL);
+    Ptr<FontInfo> current_font_info;
+    current_font_info.Attach(info_builder->GetFontInfo());
+    if (!current_font_info) {
+#if defined (SUBTLY_DEBUG)
+      fprintf(stderr, "Couldn't create font info. "
+              "No subset will be generated.\n");
+#endif
+      return NULL;
+    }
+    font_info->chars_to_glyph_ids()->insert(
+        current_font_info->chars_to_glyph_ids()->begin(),
+        current_font_info->chars_to_glyph_ids()->end());
+    font_info->resolved_glyph_ids()->insert(
+        current_font_info->resolved_glyph_ids()->begin(),
+        current_font_info->resolved_glyph_ids()->end());
+#if defined (SUBTLY_DEBUG)
+    fprintf(stderr, "Counts: chars_to_glyph_ids: %d; resoved_glyph_ids: %d\n",
+            font_info->chars_to_glyph_ids()->size(),
+            font_info->resolved_glyph_ids()->size());
+#endif
+  }
+  return font_info.Detach();
+}
+}
diff --git a/sample/subtly/merger.h b/sample/subtly/merger.h
new file mode 100644
index 0000000..43764a8
--- /dev/null
+++ b/sample/subtly/merger.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_MERGER_H_
+#define TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_MERGER_H_
+
+#include "subtly/character_predicate.h"
+#include "subtly/font_info.h"
+
+namespace sfntly {
+class Font;
+}
+
+namespace subtly {
+// Merges the subsets in the font array into a single font.
+class Merger : public sfntly::RefCounted<Merger> {
+ public:
+  explicit Merger(sfntly::FontArray* fonts);
+  virtual ~Merger() { }
+
+  // Performs merging returning the subsetted font.
+  virtual CALLER_ATTACH sfntly::Font* Merge();
+
+ protected:
+  virtual CALLER_ATTACH FontInfo* MergeFontInfos();
+
+ private:
+  FontIdMap fonts_;
+};
+}
+
+#endif  // TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_MERGER_H_
diff --git a/sample/subtly/merger_main.cc b/sample/subtly/merger_main.cc
new file mode 100644
index 0000000..a977aa7
--- /dev/null
+++ b/sample/subtly/merger_main.cc
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <map>
+#include <utility>
+
+#include "sfntly/font.h"
+#include "subtly/merger.h"
+#include "subtly/stats.h"
+#include "subtly/utils.h"
+
+using namespace subtly;
+
+void PrintUsage(const char* program_name) {
+  fprintf(stdout, "Usage: %s <input_font_file1> <input_font_file2> ..."
+          "<input_font_filen> <output_font_file>\n",
+          program_name);
+}
+
+void CheckLoading(const char* font_path, Font* font) {
+  if (!font || font->num_tables() == 0) {
+    fprintf(stderr, "Could not load font %s. Terminating.\n", font_path);
+    exit(1);
+  }
+}
+
+int main(int argc, const char** argv) {
+  if (argc < 3) {
+    PrintUsage(argv[0]);
+    exit(1);
+  }
+
+  FontArray fonts;
+  for (int32_t i = 1; i < argc - 1; ++i) {
+    Ptr<Font> font;
+    font.Attach(LoadFont(argv[i]));
+    CheckLoading(argv[i], font);
+    fonts.push_back(font);
+  }
+
+  Ptr<Merger> merger = new Merger(&fonts);
+  FontPtr new_font;
+  new_font.Attach(merger->Merge());
+
+  fprintf(stderr, "Serializing font to %s\n", argv[argc - 1]);
+  SerializeFont(argv[argc - 1], new_font);
+  if (!new_font) {
+    fprintf(stdout, "Cannot create merged font.\n");
+    return 1;
+  }
+
+  return 0;
+}
diff --git a/sample/subtly/stats.cc b/sample/subtly/stats.cc
new file mode 100644
index 0000000..769f691
--- /dev/null
+++ b/sample/subtly/stats.cc
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+
+#include "sfntly/font.h"
+#include "sfntly/table/table.h"
+#include "sfntly/tag.h"
+#include "subtly/stats.h"
+
+namespace subtly {
+using namespace sfntly;
+
+int32_t TotalFontSize(Font* font) {
+  int32_t size = 0;
+  const TableMap* table_map = font->GetTableMap();
+  for (TableMap::const_iterator it = table_map->begin(),
+           e = table_map->end(); it != e; ++it) {
+    size += it->second->DataLength();
+  }
+  return size;
+}
+
+double TableSizePercent(Font* font, int32_t tag) {
+  TablePtr table = font->GetTable(tag);
+  return static_cast<double>(table->DataLength()) / TotalFontSize(font) * 100;
+}
+
+void PrintComparison(FILE* out, Font* font, Font* new_font) {
+  fprintf(out, "====== Table Comparison (original v. subset) ======\n");
+  const TableMap* tables = font->GetTableMap();
+  for (TableMap::const_iterator it = tables->begin(),
+           e = tables->end(); it != e; ++it) {
+    char *name = TagToString(it->first);
+    int32_t size = it->second->DataLength();
+    fprintf(out, "-- %s: %d (%lf%%) ", name, size,
+            TableSizePercent(font, it->first));
+    delete[] name;
+
+    Ptr<FontDataTable> new_table = new_font->GetTable(it->first);
+    int32_t new_size = 0;
+    double size_percent = 0;
+    if (new_table) {
+      new_size = new_table->DataLength();
+      size_percent = subtly::TableSizePercent(new_font, it->first);
+    }
+
+    if (new_size == size) {
+      fprintf(out, "| same size\n");
+    } else {
+      fprintf(out, "-> %d (%lf%%) | %lf%% of original\n", new_size,
+              size_percent, static_cast<double>(new_size) / size * 100);
+    }
+  }
+}
+
+void PrintStats(FILE* out, Font* font) {
+  fprintf(out, "====== Table Stats ======\n");
+  const TableMap* tables = font->GetTableMap();
+  for (TableMap::const_iterator it = tables->begin(),
+           e = tables->end(); it != e; ++it) {
+    char *name = TagToString(it->first);
+    int32_t size = it->second->DataLength();
+    fprintf(out, "-- %s: %d (%lf%%)\n", name, size,
+            TableSizePercent(font, it->first));
+    delete[] name;
+  }
+}
+}
diff --git a/sample/subtly/stats.h b/sample/subtly/stats.h
new file mode 100644
index 0000000..89ef2ae
--- /dev/null
+++ b/sample/subtly/stats.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_STATS_H_
+#define TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_STATS_H_
+
+#include <stdio.h>
+
+#include "sfntly/port/type.h"
+
+namespace sfntly {
+class Font;
+}
+
+namespace subtly {
+using namespace sfntly;
+
+int32_t TotalFontSize(Font* font);
+
+double TableSizePercent(Font* font, int32_t tag);
+
+void PrintComparison(FILE* out, Font* font, Font* new_font);
+
+void PrintStats(FILE* out, Font* font);
+}
+
+#endif  // TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_STATS_H_
diff --git a/sample/subtly/subsetter.cc b/sample/subtly/subsetter.cc
new file mode 100644
index 0000000..d09627c
--- /dev/null
+++ b/sample/subtly/subsetter.cc
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "subtly/subsetter.h"
+
+#include <stdio.h>
+
+#include "sfntly/font.h"
+#include "sfntly/font_factory.h"
+#include "sfntly/tag.h"
+#include "subtly/character_predicate.h"
+#include "subtly/font_assembler.h"
+#include "subtly/font_info.h"
+#include "subtly/utils.h"
+
+namespace subtly {
+using namespace sfntly;
+
+/******************************************************************************
+ * Subsetter class
+ ******************************************************************************/
+Subsetter::Subsetter(Font* font, CharacterPredicate* predicate)
+    : font_(font),
+      predicate_(predicate) {
+}
+
+Subsetter::Subsetter(const char* font_path, CharacterPredicate* predicate)
+    : predicate_(predicate) {
+  font_.Attach(LoadFont(font_path));
+}
+
+CALLER_ATTACH Font* Subsetter::Subset() {
+  Ptr<FontSourcedInfoBuilder> info_builder =
+      new FontSourcedInfoBuilder(font_, 0, predicate_);
+
+  Ptr<FontInfo> font_info;
+  font_info.Attach(info_builder->GetFontInfo());
+  if (!font_info) {
+#if defined (SUBTLY_DEBUG)
+    fprintf(stderr,
+            "Couldn't create font info. No subset will be generated.\n");
+#endif
+    return NULL;
+  }
+  IntegerSet* table_blacklist = new IntegerSet;
+  table_blacklist->insert(Tag::DSIG);
+  Ptr<FontAssembler> font_assembler = new FontAssembler(font_info,
+                                                        table_blacklist);
+  Ptr<Font> font_subset;
+  font_subset.Attach(font_assembler->Assemble());
+  delete table_blacklist;
+  return font_subset.Detach();
+}
+}
diff --git a/sample/subtly/subsetter.h b/sample/subtly/subsetter.h
new file mode 100644
index 0000000..a93747f
--- /dev/null
+++ b/sample/subtly/subsetter.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_SUBSETTER_H_
+#define TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_SUBSETTER_H_
+
+#include "sfntly/font.h"
+// Cannot remove this header due to Ptr<T> instantiation issue
+#include "subtly/character_predicate.h"
+
+namespace subtly {
+// Subsets a given font using a character predicate.
+class Subsetter : public sfntly::RefCounted<Subsetter> {
+ public:
+  Subsetter(sfntly::Font* font, CharacterPredicate* predicate);
+  Subsetter(const char* font_path, CharacterPredicate* predicate);
+  virtual ~Subsetter() { }
+
+  // Performs subsetting returning the subsetted font.
+  virtual CALLER_ATTACH sfntly::Font* Subset();
+
+ private:
+  sfntly::Ptr<sfntly::Font> font_;
+  sfntly::Ptr<CharacterPredicate> predicate_;
+};
+}
+
+#endif  // TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_SUBSETTER_H_
diff --git a/sample/subtly/subsetter_main.cc b/sample/subtly/subsetter_main.cc
new file mode 100644
index 0000000..d438148
--- /dev/null
+++ b/sample/subtly/subsetter_main.cc
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <map>
+#include <utility>
+
+#include "sfntly/font.h"
+#include "subtly/character_predicate.h"
+#include "subtly/stats.h"
+#include "subtly/subsetter.h"
+#include "subtly/utils.h"
+
+using namespace subtly;
+
+void PrintUsage(const char* program_name) {
+  fprintf(stdout, "Usage: %s <input_font_file> <output_font_file>"
+          "<start_char> <end_char>\n", program_name);
+}
+
+int main(int argc, const char** argv) {
+  const char* program_name = argv[0];
+  if (argc < 5) {
+    PrintUsage(program_name);
+    exit(1);
+  }
+
+  const char* input_font_path = argv[1];
+  const char* output_font_path = argv[2];
+  FontPtr font;
+  font.Attach(subtly::LoadFont(input_font_path));
+  if (font->num_tables() == 0) {
+    fprintf(stderr, "Could not load font %s.\n", input_font_path);
+    exit(1);
+  }
+
+  const char* start_char = argv[3];
+  const char* end_char = argv[4];
+  if (start_char[1] != 0) {
+    fprintf(stderr, "Start character %c invalid.\n", start_char[0]);
+    exit(1);
+  }
+  if (end_char[1] != 0) {
+    fprintf(stderr, "Start character %c invalid.\n", end_char[0]);
+    exit(1);
+  }
+  int32_t original_size = TotalFontSize(font);
+
+
+  Ptr<CharacterPredicate> range_predicate =
+      new AcceptRange(start_char[0], end_char[0]);
+  Ptr<Subsetter> subsetter = new Subsetter(font, range_predicate);
+  Ptr<Font> new_font;
+  new_font.Attach(subsetter->Subset());
+  if (!new_font) {
+    fprintf(stdout, "Cannot create subset.\n");
+    return 0;
+  }
+
+  subtly::SerializeFont(output_font_path, new_font);
+  subtly::PrintComparison(stdout, font, new_font);
+  int32_t new_size = TotalFontSize(new_font);
+  fprintf(stdout, "Went from %d to %d: %lf%% of original\n",
+          original_size, new_size,
+          static_cast<double>(new_size) / original_size * 100);
+  return 0;
+}
diff --git a/sample/subtly/utils.cc b/sample/subtly/utils.cc
new file mode 100644
index 0000000..3c204d3
--- /dev/null
+++ b/sample/subtly/utils.cc
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "subtly/utils.h"
+
+#include "sfntly/data/growable_memory_byte_array.h"
+#include "sfntly/data/memory_byte_array.h"
+#include "sfntly/font.h"
+#include "sfntly/font_factory.h"
+#include "sfntly/port/file_input_stream.h"
+#include "sfntly/port/memory_output_stream.h"
+
+namespace subtly {
+using namespace sfntly;
+
+CALLER_ATTACH Font* LoadFont(const char* font_path) {
+  Ptr<FontFactory> font_factory;
+  font_factory.Attach(FontFactory::GetInstance());
+  FontArray fonts;
+  LoadFonts(font_path, font_factory, &fonts);
+  return fonts[0].Detach();
+}
+
+CALLER_ATTACH Font::Builder* LoadFontBuilder(const char* font_path) {
+  FontFactoryPtr font_factory;
+  font_factory.Attach(FontFactory::GetInstance());
+  FontBuilderArray builders;
+  LoadFontBuilders(font_path, font_factory, &builders);
+  return builders[0].Detach();
+}
+
+void LoadFonts(const char* font_path, FontFactory* factory, FontArray* fonts) {
+  FileInputStream input_stream;
+  input_stream.Open(font_path);
+  factory->LoadFonts(&input_stream, fonts);
+  input_stream.Close();
+}
+
+void LoadFontBuilders(const char* font_path,
+                      FontFactory* factory,
+                      FontBuilderArray* builders) {
+  FileInputStream input_stream;
+  input_stream.Open(font_path);
+  factory->LoadFontsForBuilding(&input_stream, builders);
+  input_stream.Close();
+}
+
+bool SerializeFont(const char* font_path, Font* font) {
+  if (!font_path)
+    return false;
+  FontFactoryPtr font_factory;
+  font_factory.Attach(FontFactory::GetInstance());
+  return SerializeFont(font_path, font_factory, font);
+}
+
+bool SerializeFont(const char* font_path, FontFactory* factory, Font* font) {
+  if (!font_path || !factory || !font)
+    return false;
+  // Serializing the font to a stream.
+  MemoryOutputStream output_stream;
+  factory->SerializeFont(font, &output_stream);
+  // Serializing the stream to a file.
+  FILE* output_file = NULL;
+#if defined WIN32
+  fopen_s(&output_file, font_path, "wb");
+#else
+  output_file = fopen(font_path, "wb");
+#endif
+  if (output_file == reinterpret_cast<FILE*>(NULL))
+    return false;
+  for (size_t i = 0; i < output_stream.Size(); ++i) {
+    fwrite(&(output_stream.Get()[i]), 1, 1, output_file);
+  }
+  fflush(output_file);
+  fclose(output_file);
+  return true;
+}
+};
diff --git a/sample/subtly/utils.h b/sample/subtly/utils.h
new file mode 100644
index 0000000..ba9f0d4
--- /dev/null
+++ b/sample/subtly/utils.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_UTILS_H_
+#define TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_UTILS_H_
+
+#include "sfntly/font.h"
+#include "sfntly/font_factory.h"
+
+namespace subtly {
+CALLER_ATTACH sfntly::Font* LoadFont(const char* font_path);
+CALLER_ATTACH sfntly::Font::Builder* LoadFontBuilder(const char* font_path);
+
+void LoadFonts(const char* font_path, sfntly::FontFactory* factory,
+               sfntly::FontArray* fonts);
+void LoadFontBuilders(const char* font_path,
+                      sfntly::FontFactory* factory,
+                      sfntly::FontBuilderArray* builders);
+
+bool SerializeFont(const char* font_path, sfntly::Font* font);
+bool SerializeFont(const char* font_path, sfntly::FontFactory* factory,
+                   sfntly::Font* font);
+}
+
+#endif  // TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_UTILS_H_
diff --git a/sfntly/data/byte_array.cc b/sfntly/data/byte_array.cc
new file mode 100644
index 0000000..915a40c
--- /dev/null
+++ b/sfntly/data/byte_array.cc
@@ -0,0 +1,199 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/data/byte_array.h"
+
+#include <algorithm>
+
+#include "sfntly/port/exception_type.h"
+
+namespace sfntly {
+
+const int32_t ByteArray::COPY_BUFFER_SIZE = 8192;
+
+ByteArray::~ByteArray() {}
+
+int32_t ByteArray::Length() { return filled_length_; }
+int32_t ByteArray::Size() { return storage_length_; }
+
+int32_t ByteArray::SetFilledLength(int32_t filled_length) {
+  filled_length_ = std::min<int32_t>(filled_length, storage_length_);
+  return filled_length_;
+}
+
+int32_t ByteArray::Get(int32_t index) {
+  return InternalGet(index) & 0xff;
+}
+
+int32_t ByteArray::Get(int32_t index, ByteVector* b) {
+  assert(b);
+  return Get(index, &((*b)[0]), 0, b->size());
+}
+
+int32_t ByteArray::Get(int32_t index,
+                       byte_t* b,
+                       int32_t offset,
+                       int32_t length) {
+  assert(b);
+  if (index < 0 || index >= filled_length_) {
+    return 0;
+  }
+  int32_t actual_length = std::min<int32_t>(length, filled_length_ - index);
+  return InternalGet(index, b, offset, actual_length);
+}
+
+void ByteArray::Put(int32_t index, byte_t b) {
+  if (index < 0 || index >= Size()) {
+#if defined (SFNTLY_NO_EXCEPTION)
+    return;
+#else
+    throw IndexOutOfBoundException(
+        "Attempt to write outside the bounds of the data");
+#endif
+  }
+  InternalPut(index, b);
+  filled_length_ = std::max<int32_t>(filled_length_, index + 1);
+}
+
+int32_t ByteArray::Put(int index, ByteVector* b) {
+  assert(b);
+  return Put(index, &((*b)[0]), 0, b->size());
+}
+
+int32_t ByteArray::Put(int32_t index,
+                       byte_t* b,
+                       int32_t offset,
+                       int32_t length) {
+  assert(b);
+  if (index < 0 || index >= Size()) {
+#if defined (SFNTLY_NO_EXCEPTION)
+    return 0;
+#else
+    throw IndexOutOfBoundException(
+        "Attempt to write outside the bounds of the data");
+#endif
+  }
+  int32_t actual_length = std::min<int32_t>(length, Size() - index);
+  int32_t bytes_written = InternalPut(index, b, offset, actual_length);
+  filled_length_ = std::max<int32_t>(filled_length_, index + bytes_written);
+  return bytes_written;
+}
+
+int32_t ByteArray::CopyTo(ByteArray* array) {
+  return CopyTo(array, 0, Length());
+}
+
+int32_t ByteArray::CopyTo(ByteArray* array, int32_t offset, int32_t length) {
+  return CopyTo(0, array, offset, length);
+}
+
+int32_t ByteArray::CopyTo(int32_t dst_offset, ByteArray* array,
+                          int32_t src_offset, int32_t length) {
+  assert(array);
+  if (array->Size() < dst_offset + length) {  // insufficient space
+    return -1;
+  }
+
+  ByteVector b(COPY_BUFFER_SIZE);
+  int32_t bytes_read = 0;
+  int32_t index = 0;
+  int32_t remaining_length = length;
+  int32_t buffer_length = std::min<int32_t>(COPY_BUFFER_SIZE, length);
+  while ((bytes_read =
+              Get(index + src_offset, &(b[0]), 0, buffer_length)) > 0) {
+    int bytes_written = array->Put(index + dst_offset, &(b[0]), 0, bytes_read);
+    UNREFERENCED_PARAMETER(bytes_written);
+    index += bytes_read;
+    remaining_length -= bytes_read;
+    buffer_length = std::min<int32_t>(b.size(), remaining_length);
+  }
+  return index;
+}
+
+int32_t ByteArray::CopyTo(OutputStream* os) {
+    return CopyTo(os, 0, Length());
+}
+
+int32_t ByteArray::CopyTo(OutputStream* os, int32_t offset, int32_t length) {
+  ByteVector b(COPY_BUFFER_SIZE);
+  int32_t bytes_read = 0;
+  int32_t index = 0;
+  int32_t buffer_length = std::min<int32_t>(COPY_BUFFER_SIZE, length);
+  while ((bytes_read = Get(index + offset, &(b[0]), 0, buffer_length)) > 0) {
+    os->Write(&b, 0, bytes_read);
+    index += bytes_read;
+    buffer_length = std::min<int32_t>(b.size(), length - index);
+  }
+  return index;
+}
+
+bool ByteArray::CopyFrom(InputStream* is, int32_t length) {
+  ByteVector b(COPY_BUFFER_SIZE);
+  int32_t bytes_read = 0;
+  int32_t index = 0;
+  int32_t buffer_length = std::min<int32_t>(COPY_BUFFER_SIZE, length);
+  while ((bytes_read = is->Read(&b, 0, buffer_length)) > 0) {
+    if (Put(index, &(b[0]), 0, bytes_read) != bytes_read) {
+#if defined (SFNTLY_NO_EXCEPTION)
+      return 0;
+#else
+      throw IOException("Error writing bytes.");
+#endif
+    }
+    index += bytes_read;
+    length -= bytes_read;
+    buffer_length = std::min<int32_t>(b.size(), length);
+  }
+  return true;
+}
+
+bool ByteArray::CopyFrom(InputStream* is) {
+  ByteVector b(COPY_BUFFER_SIZE);
+  int32_t bytes_read = 0;
+  int32_t index = 0;
+  int32_t buffer_length = COPY_BUFFER_SIZE;
+  while ((bytes_read = is->Read(&b, 0, buffer_length)) > 0) {
+    if (Put(index, &b[0], 0, bytes_read) != bytes_read) {
+#if defined (SFNTLY_NO_EXCEPTION)
+      return 0;
+#else
+      throw IOException("Error writing bytes.");
+#endif
+    }
+    index += bytes_read;
+  }
+  return true;
+}
+
+ByteArray::ByteArray(int32_t filled_length,
+                     int32_t storage_length,
+                     bool growable) {
+  Init(filled_length, storage_length, growable);
+}
+
+ByteArray::ByteArray(int32_t filled_length, int32_t storage_length) {
+  Init(filled_length, storage_length, false);
+}
+
+void ByteArray::Init(int32_t filled_length,
+                     int32_t storage_length,
+                     bool growable) {
+  storage_length_ = storage_length;
+  growable_ = growable;
+  SetFilledLength(filled_length);
+}
+
+}  // namespace sfntly
diff --git a/sfntly/data/byte_array.h b/sfntly/data/byte_array.h
new file mode 100644
index 0000000..70dc92f
--- /dev/null
+++ b/sfntly/data/byte_array.h
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2011 The sfntly 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_DATA_BYTE_ARRAY_H_
+#define SFNTLY_CPP_SRC_SFNTLY_DATA_BYTE_ARRAY_H_
+
+#include "sfntly/port/refcount.h"
+#include "sfntly/port/type.h"
+#include "sfntly/port/input_stream.h"
+#include "sfntly/port/output_stream.h"
+
+namespace sfntly {
+
+// An abstraction to a contiguous array of bytes.
+// C++ port of this class assumes that the data are stored in a linear region
+// like std::vector.
+class ByteArray : virtual public RefCount {
+ public:
+  virtual ~ByteArray();
+
+  // Gets the current filled and readable length of the array.
+  int32_t Length();
+
+  // Gets the maximum size of the array. This is the maximum number of bytes that
+  // the array can hold and all of it may not be filled with data or even fully
+  // allocated yet.
+  int32_t Size();
+
+  // Determines whether or not this array is growable or of fixed size.
+  bool growable() { return growable_; }
+
+  int32_t SetFilledLength(int32_t filled_length);
+
+  // Gets the byte from the given index.
+  // @param index the index into the byte array
+  // @return the byte or -1 if reading beyond the bounds of the data
+  virtual int32_t Get(int32_t index);
+
+  // Gets the bytes from the given index and fill the buffer with them. As many
+  // bytes as will fit into the buffer are read unless that would go past the
+  // end of the array.
+  // @param index the index into the byte array
+  // @param b the buffer to put the bytes read into
+  // @return the number of bytes read from the buffer
+  virtual int32_t Get(int32_t index, ByteVector* b);
+
+  // Gets the bytes from the given index and fill the buffer with them starting
+  // at the offset given. As many bytes as the specified length are read unless
+  // that would go past the end of the array.
+  // @param index the index into the byte array
+  // @param b the buffer to put the bytes read into
+  // @param offset the location in the buffer to start putting the bytes
+  // @param length the number of bytes to put into the buffer
+  // @return the number of bytes read from the buffer
+  virtual int32_t Get(int32_t index,
+                      byte_t* b,
+                      int32_t offset,
+                      int32_t length);
+
+  // Puts the specified byte into the array at the given index unless that would
+  // be beyond the length of the array and it isn't growable.
+  virtual void Put(int32_t index, byte_t b);
+
+  // Puts the specified bytes into the array at the given index. The entire
+  // buffer is put into the array unless that would extend beyond the length and
+  // the array isn't growable.
+  virtual int32_t Put(int32_t index, ByteVector* b);
+
+  // Puts the specified bytes into the array at the given index. All of the bytes
+  // specified are put into the array unless that would extend beyond the length
+  // and the array isn't growable. The bytes to be put into the array are those
+  // in the buffer from the given offset and for the given length.
+  // @param index the index into the ByteArray
+  // @param b the bytes to put into the array
+  // @param offset the offset in the bytes to start copying from
+  // @param length the number of bytes to copy into the array
+  // @return the number of bytes actually written
+  virtual int32_t Put(int32_t index,
+                      byte_t* b,
+                      int32_t offset,
+                      int32_t length);
+
+  // Fully copies this ByteArray to another ByteArray to the extent that the
+  // destination array has storage for the data copied.
+  virtual int32_t CopyTo(ByteArray* array);
+
+  // Copies a segment of this ByteArray to another ByteArray.
+  // @param array the destination
+  // @param offset the offset in this ByteArray to start copying from
+  // @param length the maximum length in bytes to copy
+  // @return the number of bytes copied
+  virtual int32_t CopyTo(ByteArray* array, int32_t offset, int32_t length);
+
+  // Copies this ByteArray to another ByteArray.
+  // @param dstOffset the offset in the destination array to start copying to
+  // @param array the destination
+  // @param srcOffset the offset in this ByteArray to start copying from
+  // @param length the maximum length in bytes to copy
+  // @return the number of bytes copied
+  virtual int32_t CopyTo(int32_t dst_offset,
+                         ByteArray* array,
+                         int32_t src_offset,
+                         int32_t length);
+
+  // Copies this ByteArray to an OutputStream.
+  // @param os the destination
+  // @return the number of bytes copied
+  virtual int32_t CopyTo(OutputStream* os);
+
+  // Copies this ByteArray to an OutputStream.
+  // @param os the destination
+  // @param offset
+  // @param length
+  // @return the number of bytes copied
+  virtual int32_t CopyTo(OutputStream* os, int32_t offset, int32_t length);
+
+  // Copies from the InputStream into this ByteArray.
+  // @param is the source
+  // @param length the number of bytes to copy
+  virtual bool CopyFrom(InputStream* is, int32_t length);
+
+  // Copies everything from the InputStream into this ByteArray.
+  // @param is the source
+  virtual bool CopyFrom(InputStream* is);
+
+ protected:
+  // filledLength the length that is "filled" and readable counting from offset.
+  // storageLength the maximum storage size of the underlying data.
+  // growable is the storage growable - storageLength is the max growable size.
+  ByteArray(int32_t filled_length, int32_t storage_length, bool growable);
+  ByteArray(int32_t filled_length, int32_t storage_length);
+  void Init(int32_t filled_length, int32_t storage_length, bool growable);
+
+  // Internal subclass API
+
+  // Stores the byte at the index given.
+  // @param index the location to store at
+  // @param b the byte to store
+  virtual void InternalPut(int32_t index, byte_t b) = 0;
+
+  // Stores the array of bytes at the given index.
+  // @param index the location to store at
+  // @param b the bytes to store
+  // @param offset the offset to start from in the byte array
+  // @param length the length of the byte array to store from the offset
+  // @return the number of bytes actually stored
+  virtual int32_t InternalPut(int32_t index,
+                              byte_t* b,
+                              int32_t offset,
+                              int32_t length) = 0;
+
+  // Gets the byte at the index given.
+  // @param index the location to get from
+  // @return the byte stored at the index
+  virtual byte_t InternalGet(int32_t index) = 0;
+
+  // Gets the bytes at the index given of the given length.
+  // @param index the location to start getting from
+  // @param b the array to put the bytes into
+  // @param offset the offset in the array to put the bytes into
+  // @param length the length of bytes to read
+  // @return the number of bytes actually ready
+  virtual int32_t InternalGet(int32_t index,
+                              byte_t* b,
+                              int32_t offset,
+                              int32_t length) = 0;
+
+  // Close this instance of the ByteArray.
+  virtual void Close() = 0;
+
+  // C++ port only, raw pointer to the first element of storage.
+  virtual byte_t* Begin() = 0;
+
+  // Java toString() not ported.
+
+  static const int32_t COPY_BUFFER_SIZE;
+
+ private:
+  //bool bound_;  // unused, comment out
+  int32_t filled_length_;
+  int32_t storage_length_;
+  bool growable_;
+};
+typedef Ptr<ByteArray> ByteArrayPtr;
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_DATA_BYTE_ARRAY_H_
diff --git a/sfntly/data/font_data.cc b/sfntly/data/font_data.cc
new file mode 100644
index 0000000..d2b95ea
--- /dev/null
+++ b/sfntly/data/font_data.cc
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include <limits.h>
+#include <algorithm>
+#include <functional>
+
+#include "sfntly/data/font_data.h"
+
+namespace sfntly {
+
+int32_t FontData::Size() const {
+  return std::min<int32_t>(array_->Size() - bound_offset_, bound_length_);
+}
+
+bool FontData::Bound(int32_t offset, int32_t length) {
+  if (offset + length > Size() || offset < 0 || length < 0)
+    return false;
+
+  bound_offset_ += offset;
+  bound_length_ = length;
+  return true;
+}
+
+bool FontData::Bound(int32_t offset) {
+if (offset > Size() || offset < 0)
+    return false;
+
+  bound_offset_ += offset;
+  return true;
+}
+
+int32_t FontData::Length() const {
+  return std::min<int32_t>(array_->Length() - bound_offset_, bound_length_);
+}
+
+FontData::FontData(ByteArray* ba) {
+  Init(ba);
+}
+
+FontData::FontData(FontData* data, int32_t offset, int32_t length) {
+  Init(data->array_);
+  Bound(data->bound_offset_ + offset, length);
+}
+
+FontData::FontData(FontData* data, int32_t offset) {
+  Init(data->array_);
+  Bound(data->bound_offset_ + offset,
+        (data->bound_length_ == GROWABLE_SIZE)
+            ? GROWABLE_SIZE : data->bound_length_ - offset);
+}
+
+FontData::~FontData() {}
+
+void FontData::Init(ByteArray* ba) {
+  array_ = ba;
+  bound_offset_ = 0;
+  bound_length_ = GROWABLE_SIZE;
+}
+
+int32_t FontData::BoundOffset(int32_t offset) {
+  return offset + bound_offset_;
+}
+
+int32_t FontData::BoundLength(int32_t offset, int32_t length) {
+  return std::min<int32_t>(length, bound_length_ - offset);
+}
+
+}  // namespace sfntly
diff --git a/sfntly/data/font_data.h b/sfntly/data/font_data.h
new file mode 100644
index 0000000..d02e8b7
--- /dev/null
+++ b/sfntly/data/font_data.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_DATA_FONT_DATA_H_
+#define SFNTLY_CPP_SRC_SFNTLY_DATA_FONT_DATA_H_
+
+#include <limits.h>
+
+#include <vector>
+
+#include "sfntly/port/type.h"
+#include "sfntly/data/byte_array.h"
+#include "sfntly/port/refcount.h"
+
+namespace sfntly {
+
+struct DataSize {
+  enum {
+    kBYTE = 1,
+    kCHAR = 1,
+    kUSHORT = 2,
+    kSHORT = 2,
+    kUINT24 = 3,
+    kULONG = 4,
+    kLONG = 4,
+    kFixed = 4,
+    kFUNIT = 4,
+    kFWORD = 2,
+    kUFWORD = 2,
+    kF2DOT14 = 2,
+    kLONGDATETIME = 8,
+    kTag = 4,
+    kGlyphID = 2,
+    kOffset = 2
+  };
+};
+
+class FontData : virtual public RefCount {
+ public:
+  // Gets the maximum size of the FontData. This is the maximum number of bytes
+  // that the font data can hold and all of it may not be filled with data or
+  // even fully allocated yet.
+  // @return the maximum size of this font data
+  virtual int32_t Size() const;
+
+  // Sets limits on the size of the FontData. The FontData is then only
+  // visible within the bounds set.
+  // @param offset the start of the new bounds
+  // @param length the number of bytes in the bounded array
+  // @return true if the bounding range was successful; false otherwise
+  virtual bool Bound(int32_t offset, int32_t length);
+
+  // Sets limits on the size of the FontData. This is a offset bound only so if
+  // the FontData is writable and growable then there is no limit to that growth
+  // from the bounding operation.
+  // @param offset the start of the new bounds which must be within the current
+  //        size of the FontData
+  // @return true if the bounding range was successful; false otherwise
+  virtual bool Bound(int32_t offset);
+
+  // Makes a slice of this FontData. The returned slice will share the data with
+  // the original <code>FontData</code>.
+  // @param offset the start of the slice
+  // @param length the number of bytes in the slice
+  // @return a slice of the original FontData
+  virtual CALLER_ATTACH FontData* Slice(int32_t offset, int32_t length) = 0;
+
+  // Makes a bottom bound only slice of this array. The returned slice will
+  // share the data with the original <code>FontData</code>.
+  // @param offset the start of the slice
+  // @return a slice of the original FontData
+  virtual CALLER_ATTACH FontData* Slice(int32_t offset) = 0;
+
+  // Gets the length of the data.
+  virtual int32_t Length() const;
+
+ protected:
+  // Constructor.
+  // @param ba the byte array to use for the backing data
+  explicit FontData(ByteArray* ba);
+
+  // Constructor.
+  // @param data the data to wrap
+  // @param offset the offset to start the wrap from
+  // @param length the length of the data wrapped
+  FontData(FontData* data, int32_t offset, int32_t length);
+
+  // Constructor.
+  // @param data the data to wrap
+  // @param offset the offset to start the wrap from
+  FontData(FontData* data, int32_t offset);
+  virtual ~FontData();
+
+  void Init(ByteArray* ba);
+
+  // Gets the offset in the underlying data taking into account any bounds on
+  // the data.
+  // @param offset the offset to get the bound compensated offset for
+  // @return the bound compensated offset
+  int32_t BoundOffset(int32_t offset);
+
+  // Gets the length in the underlying data taking into account any bounds on
+  // the data.
+  // @param offset the offset that the length is being used at
+  // @param length the length to get the bound compensated length for
+  // @return the bound compensated length
+  int32_t BoundLength(int32_t offset, int32_t length);
+
+  static const int32_t GROWABLE_SIZE = INT_MAX;
+
+  // TODO(arthurhsu): style guide violation: refactor this protected member
+  ByteArrayPtr array_;
+
+ private:
+  int32_t bound_offset_;
+  int32_t bound_length_;
+};
+typedef Ptr<FontData> FontDataPtr;
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_DATA_FONT_DATA_H_
diff --git a/sfntly/data/font_input_stream.cc b/sfntly/data/font_input_stream.cc
new file mode 100644
index 0000000..dcf8be3
--- /dev/null
+++ b/sfntly/data/font_input_stream.cc
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/data/font_input_stream.h"
+
+#include <algorithm>
+
+namespace sfntly {
+
+FontInputStream::FontInputStream(InputStream* is)
+    : stream_(is), position_(0), length_(0), bounded_(false) {
+}
+
+FontInputStream::FontInputStream(InputStream* is, size_t length)
+    : stream_(is), position_(0), length_(length), bounded_(true) {
+}
+
+FontInputStream::~FontInputStream() {
+  // Do not close here, underlying InputStream will close themselves.
+}
+
+int32_t FontInputStream::Available() {
+  if (stream_) {
+    return stream_->Available();
+  }
+  return 0;
+}
+
+void FontInputStream::Close() {
+  if (stream_) {
+    stream_->Close();
+  }
+}
+
+void FontInputStream::Mark(int32_t readlimit) {
+  if (stream_) {
+    stream_->Mark(readlimit);
+  }
+}
+
+bool FontInputStream::MarkSupported() {
+  if (stream_) {
+    return stream_->MarkSupported();
+  }
+  return false;
+}
+
+void FontInputStream::Reset() {
+  if (stream_) {
+    stream_->Reset();
+  }
+}
+
+int32_t FontInputStream::Read() {
+  if (!stream_ || (bounded_ && position_ >= length_)) {
+    return -1;
+  }
+  int32_t b = stream_->Read();
+  if (b >= 0) {
+    position_++;
+  }
+  return b;
+}
+
+int32_t FontInputStream::Read(ByteVector* b, int32_t offset, int32_t length) {
+  if (!stream_ || offset < 0 || length < 0 ||
+      (bounded_ && position_ >= length_)) {
+    return -1;
+  }
+  int32_t bytes_to_read =
+      bounded_ ? std::min<int32_t>(length, (int32_t)(length_ - position_)) :
+                 length;
+  int32_t bytes_read = stream_->Read(b, offset, bytes_to_read);
+  position_ += bytes_read;
+  return bytes_read;
+}
+
+int32_t FontInputStream::Read(ByteVector* b) {
+  return Read(b, 0, b->size());
+}
+
+int32_t FontInputStream::ReadChar() {
+  return Read();
+}
+
+int32_t FontInputStream::ReadUShort() {
+  return 0xffff & (Read() << 8 | Read());
+}
+
+int32_t FontInputStream::ReadShort() {
+  return ((Read() << 8 | Read()) << 16) >> 16;
+}
+
+int32_t FontInputStream::ReadUInt24() {
+  return 0xffffff & (Read() << 16 | Read() << 8 | Read());
+}
+
+int64_t FontInputStream::ReadULong() {
+  return 0xffffffffL & ReadLong();
+}
+
+int32_t FontInputStream::ReadULongAsInt() {
+  int64_t ulong = ReadULong();
+  return ((int32_t)ulong) & ~0x80000000;
+}
+
+int32_t FontInputStream::ReadLong() {
+  return Read() << 24 | Read() << 16 | Read() << 8 | Read();
+}
+
+int32_t FontInputStream::ReadFixed() {
+  return ReadLong();
+}
+
+int64_t FontInputStream::ReadDateTimeAsLong() {
+  return (int64_t)ReadULong() << 32 | ReadULong();
+}
+
+int64_t FontInputStream::Skip(int64_t n) {
+  if (stream_) {
+    int64_t skipped = stream_->Skip(n);
+    position_ += skipped;
+    return skipped;
+  }
+  return 0;
+}
+
+}  // namespace sfntly
diff --git a/sfntly/data/font_input_stream.h b/sfntly/data/font_input_stream.h
new file mode 100644
index 0000000..9992b07
--- /dev/null
+++ b/sfntly/data/font_input_stream.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_DATA_FONT_INPUT_STREAM_H_
+#define SFNTLY_CPP_SRC_SFNTLY_DATA_FONT_INPUT_STREAM_H_
+
+#include "sfntly/port/type.h"
+#include "sfntly/port/input_stream.h"
+
+namespace sfntly {
+
+// An input stream for reading font data.
+// The data types used are as listed:
+// BYTE       8-bit unsigned integer.
+// CHAR       8-bit signed integer.
+// USHORT     16-bit unsigned integer.
+// SHORT      16-bit signed integer.
+// UINT24     24-bit unsigned integer.
+// ULONG      32-bit unsigned integer.
+// LONG       32-bit signed integer.
+// Fixed      32-bit signed fixed-point number (16.16)
+// FUNIT      Smallest measurable distance in the em space.
+// FWORD      16-bit signed integer (SHORT) that describes a quantity in FUnits.
+// UFWORD     16-bit unsigned integer (USHORT) that describes a quantity in
+//            FUnits.
+// F2DOT14    16-bit signed fixed number with the low 14 bits of fraction (2.14)
+// LONGDATETIME  Date represented in number of seconds since 12:00 midnight,
+//               January 1, 1904. The value is represented as a signed 64-bit
+//               integer.
+
+// Note: Original class inherits from Java's FilterOutputStream, which wraps
+//       an InputStream within.  In C++, we directly do the wrapping without
+//       defining another layer of abstraction.  The wrapped output stream is
+//       *NOT* reference counted (because it's meaningless to ref-count an I/O
+//       stream).
+class FontInputStream : public InputStream {
+ public:
+  // Constructor.
+  // @param is input stream to wrap
+  explicit FontInputStream(InputStream* is);
+
+  // Constructor for a bounded font input stream.
+  // @param is input stream to wrap
+  // @param length the maximum length of bytes to read
+  FontInputStream(InputStream* is, size_t length);
+
+  virtual ~FontInputStream();
+
+
+  virtual int32_t Available();
+  virtual void Close();
+  virtual void Mark(int32_t readlimit);
+  virtual bool MarkSupported();
+  virtual void Reset();
+
+  virtual int32_t Read();
+  virtual int32_t Read(ByteVector* buffer);
+  virtual int32_t Read(ByteVector* buffer, int32_t offset, int32_t length);
+
+  // Get the current position in the stream in bytes.
+  // @return the current position in bytes
+  virtual int64_t position() { return position_; }
+
+  virtual int32_t ReadChar();
+  virtual int32_t ReadUShort();
+  virtual int32_t ReadShort();
+  virtual int32_t ReadUInt24();
+  virtual int64_t ReadULong();
+  virtual int32_t ReadULongAsInt();
+  virtual int32_t ReadLong();
+  virtual int32_t ReadFixed();
+  virtual int64_t ReadDateTimeAsLong();
+  virtual int64_t Skip(int64_t n);  // n can be negative.
+
+ private:
+  InputStream* stream_;
+  int64_t position_;
+  int64_t length_;  // Bound on length of data to read.
+  bool bounded_;
+};
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_DATA_FONT_INPUT_STREAM_H_
diff --git a/sfntly/data/font_output_stream.cc b/sfntly/data/font_output_stream.cc
new file mode 100644
index 0000000..3422a22
--- /dev/null
+++ b/sfntly/data/font_output_stream.cc
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/data/font_output_stream.h"
+
+#include <algorithm>
+
+namespace sfntly {
+
+FontOutputStream::FontOutputStream(OutputStream* os)
+    : stream_(os),
+      position_(0) {
+}
+
+FontOutputStream::~FontOutputStream() {
+  // Do not close, underlying stream shall clean up themselves.
+}
+
+void FontOutputStream::Write(byte_t b) {
+  if (stream_) {
+    stream_->Write(b);
+    position_++;
+  }
+}
+
+void FontOutputStream::Write(ByteVector* b) {
+  if (b) {
+    Write(b, 0, b->size());
+    position_ += b->size();
+  }
+}
+
+void FontOutputStream::Write(ByteVector* b, int32_t off, int32_t len) {
+  assert(b);
+  assert(stream_);
+  if (off < 0 || len < 0 || off + len < 0 ||
+      static_cast<size_t>(off + len) > b->size()) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IndexOutOfBoundException();
+#else
+    return;
+#endif
+  }
+
+  stream_->Write(b, off, len);
+  position_ += len;
+}
+
+void FontOutputStream::Write(byte_t* b, int32_t off, int32_t len) {
+  assert(b);
+  assert(stream_);
+  if (off < 0 || len < 0 || off + len < 0) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IndexOutOfBoundException();
+#else
+    return;
+#endif
+  }
+
+  stream_->Write(b, off, len);
+  position_ += len;
+}
+
+void FontOutputStream::WriteChar(byte_t c) {
+  Write(c);
+}
+
+void FontOutputStream::WriteUShort(int32_t us) {
+  Write((byte_t)((us >> 8) & 0xff));
+  Write((byte_t)(us & 0xff));
+}
+
+void FontOutputStream::WriteShort(int32_t s) {
+  WriteUShort(s);
+}
+
+void FontOutputStream::WriteUInt24(int32_t ui) {
+  Write((byte_t)(ui >> 16) & 0xff);
+  Write((byte_t)(ui >> 8) & 0xff);
+  Write((byte_t)ui & 0xff);
+}
+
+void FontOutputStream::WriteULong(int64_t ul) {
+  Write((byte_t)((ul >> 24) & 0xff));
+  Write((byte_t)((ul >> 16) & 0xff));
+  Write((byte_t)((ul >> 8) & 0xff));
+  Write((byte_t)(ul & 0xff));
+}
+
+void FontOutputStream::WriteLong(int64_t l) {
+  WriteULong(l);
+}
+
+void FontOutputStream::WriteFixed(int32_t f) {
+  WriteULong(f);
+}
+
+void FontOutputStream::WriteDateTime(int64_t date) {
+  WriteULong((date >> 32) & 0xffffffff);
+  WriteULong(date & 0xffffffff);
+}
+
+void FontOutputStream::Flush() {
+  if (stream_) {
+    stream_->Flush();
+  }
+}
+
+void FontOutputStream::Close() {
+  if (stream_) {
+    stream_->Flush();
+    stream_->Close();
+    position_ = 0;
+  }
+}
+
+}  // namespace sfntly
diff --git a/sfntly/data/font_output_stream.h b/sfntly/data/font_output_stream.h
new file mode 100644
index 0000000..fcd48e8
--- /dev/null
+++ b/sfntly/data/font_output_stream.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_DATA_FONT_OUTPUT_STREAM_H_
+#define SFNTLY_CPP_SRC_SFNTLY_DATA_FONT_OUTPUT_STREAM_H_
+
+#include "sfntly/port/type.h"
+#include "sfntly/port/output_stream.h"
+
+namespace sfntly {
+
+// An output stream for writing font data.
+// The data types used are as listed:
+// BYTE       8-bit unsigned integer.
+// CHAR       8-bit signed integer.
+// USHORT     16-bit unsigned integer.
+// SHORT      16-bit signed integer.
+// UINT24     24-bit unsigned integer.
+// ULONG      32-bit unsigned integer.
+// LONG       32-bit signed integer.
+// Fixed      32-bit signed fixed-point number (16.16)
+// FUNIT      Smallest measurable distance in the em space.
+// FWORD      16-bit signed integer (SHORT) that describes a quantity in FUnits.
+// UFWORD     16-bit unsigned integer (USHORT) that describes a quantity in
+//            FUnits.
+// F2DOT14    16-bit signed fixed number with the low 14 bits of fraction (2.14)
+// LONGDATETIME  Date represented in number of seconds since 12:00 midnight,
+//               January 1, 1904. The value is represented as a signed 64-bit
+//               integer.
+
+// Note: The wrapped output stream is *NOT* reference counted (because it's
+//       meaningless to ref-count an I/O stream).
+class FontOutputStream : public OutputStream {
+ public:
+  explicit FontOutputStream(OutputStream* os);
+  virtual ~FontOutputStream();
+
+  virtual size_t position() { return position_; }
+
+  virtual void Write(byte_t b);
+  virtual void Write(ByteVector* b);
+  virtual void Write(ByteVector* b, int32_t off, int32_t len);
+  virtual void Write(byte_t* b, int32_t off, int32_t len);
+  virtual void WriteChar(byte_t c);
+  virtual void WriteUShort(int32_t us);
+  virtual void WriteShort(int32_t s);
+  virtual void WriteUInt24(int32_t ui);
+  virtual void WriteULong(int64_t ul);
+  virtual void WriteLong(int64_t l);
+  virtual void WriteFixed(int32_t l);
+  virtual void WriteDateTime(int64_t date);
+
+  // Note: C++ port only.
+  virtual void Flush();
+  virtual void Close();
+
+ private:
+  // Note: we do not use the variable name out as in Java because it has
+  //       special meaning in VC++ and will be very confusing.
+  OutputStream* stream_;
+  size_t position_;
+};
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_DATA_FONT_OUTPUT_STREAM_H_
diff --git a/sfntly/data/growable_memory_byte_array.cc b/sfntly/data/growable_memory_byte_array.cc
new file mode 100644
index 0000000..c335614
--- /dev/null
+++ b/sfntly/data/growable_memory_byte_array.cc
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/data/growable_memory_byte_array.h"
+
+#include <limits.h>
+#include <string.h>
+
+#include <algorithm>
+
+namespace sfntly {
+
+GrowableMemoryByteArray::GrowableMemoryByteArray()
+    : ByteArray(0, INT_MAX, true) {
+  // Note: We did not set an initial size of array like Java because STL
+  //       implementation will determine the best strategy.
+}
+
+GrowableMemoryByteArray::~GrowableMemoryByteArray() {}
+
+int32_t GrowableMemoryByteArray::CopyTo(OutputStream* os,
+                                        int32_t offset,
+                                        int32_t length) {
+  assert(os);
+  os->Write(&b_, offset, length);
+  return length;
+}
+
+void GrowableMemoryByteArray::InternalPut(int32_t index, byte_t b) {
+  if ((size_t)index >= b_.size()) {
+    b_.resize((size_t)(index + 1));
+  }
+  b_[index] = b;
+}
+
+int32_t GrowableMemoryByteArray::InternalPut(int32_t index,
+                                             byte_t* b,
+                                             int32_t offset,
+                                             int32_t length) {
+  if ((size_t)index + length >= b_.size()) {
+    // Note: We grow one byte more than Java version. VC debuggers shows
+    //       data better this way.
+    b_.resize((size_t)(index + length + 1));
+  }
+  std::copy(b + offset, b + offset + length, b_.begin() + index);
+  return length;
+}
+
+byte_t GrowableMemoryByteArray::InternalGet(int32_t index) {
+  return b_[index];
+}
+
+int32_t GrowableMemoryByteArray::InternalGet(int32_t index,
+                                             byte_t* b,
+                                             int32_t offset,
+                                             int32_t length) {
+  memcpy(b + offset, &(b_[0]) + index, length);
+  return length;
+}
+
+void GrowableMemoryByteArray::Close() {
+  b_.clear();
+}
+
+byte_t* GrowableMemoryByteArray::Begin() {
+  return &(b_[0]);
+}
+
+}  // namespace sfntly
diff --git a/sfntly/data/growable_memory_byte_array.h b/sfntly/data/growable_memory_byte_array.h
new file mode 100644
index 0000000..8583a0d
--- /dev/null
+++ b/sfntly/data/growable_memory_byte_array.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_DATA_GROWABLE_MEMORY_BYTE_ARRAY_H_
+#define SFNTLY_CPP_SRC_SFNTLY_DATA_GROWABLE_MEMORY_BYTE_ARRAY_H_
+
+#include "sfntly/data/byte_array.h"
+
+namespace sfntly {
+
+// Note: This is not really a port of Java version. Instead, this wraps a
+//       std::vector inside and let it grow by calling resize().
+class GrowableMemoryByteArray : public ByteArray,
+                                public RefCounted<GrowableMemoryByteArray> {
+ public:
+  GrowableMemoryByteArray();
+  virtual ~GrowableMemoryByteArray();
+  virtual int32_t CopyTo(OutputStream* os, int32_t offset, int32_t length);
+
+  // Make gcc -Woverloaded-virtual happy.
+  virtual int32_t CopyTo(ByteArray* array) { return ByteArray::CopyTo(array); }
+  virtual int32_t CopyTo(ByteArray* array, int32_t offset, int32_t length) {
+    return ByteArray::CopyTo(array, offset, length);
+  }
+  virtual int32_t CopyTo(int32_t dst_offset,
+                         ByteArray* array,
+                         int32_t src_offset,
+                         int32_t length) {
+    return ByteArray::CopyTo(dst_offset, array, src_offset, length);
+  }
+  virtual int32_t CopyTo(OutputStream* os) { return ByteArray::CopyTo(os); }
+
+ protected:
+  virtual void InternalPut(int32_t index, byte_t b);
+  virtual int32_t InternalPut(int32_t index,
+                              byte_t* b,
+                              int32_t offset,
+                              int32_t length);
+  virtual byte_t InternalGet(int32_t index);
+  virtual int32_t InternalGet(int32_t index,
+                              byte_t* b,
+                              int32_t offset,
+                              int32_t length);
+  virtual void Close();
+  virtual byte_t* Begin();
+
+ private:
+  ByteVector b_;
+};
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_DATA_GROWABLE_MEMORY_BYTE_ARRAY_H_
diff --git a/sfntly/data/memory_byte_array.cc b/sfntly/data/memory_byte_array.cc
new file mode 100644
index 0000000..d6c9c48
--- /dev/null
+++ b/sfntly/data/memory_byte_array.cc
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/data/memory_byte_array.h"
+
+#include <string.h>
+
+namespace sfntly {
+
+MemoryByteArray::MemoryByteArray(int32_t length)
+    : ByteArray(0, length), b_(NULL), allocated_(true) {
+}
+
+MemoryByteArray::MemoryByteArray(byte_t* b, int32_t filled_length)
+    : ByteArray(filled_length, filled_length), b_(b), allocated_(false) {
+  assert(b);
+}
+
+MemoryByteArray::~MemoryByteArray() {
+  Close();
+}
+
+int32_t MemoryByteArray::CopyTo(OutputStream* os,
+                                int32_t offset,
+                                int32_t length) {
+  assert(os);
+  os->Write(b_, offset, length);
+  return length;
+}
+
+void MemoryByteArray::Init() {
+  if (allocated_ && b_ == NULL) {
+    b_ = new byte_t[Size()];
+    memset(b_, 0, Size());
+  }
+}
+
+void MemoryByteArray::InternalPut(int32_t index, byte_t b) {
+  Init();
+  b_[index] = b;
+}
+
+int32_t MemoryByteArray::InternalPut(int32_t index,
+                                     byte_t* b,
+                                     int32_t offset,
+                                     int32_t length) {
+  assert(b);
+  Init();
+  memcpy(b_ + index, b + offset, length);
+  return length;
+}
+
+byte_t MemoryByteArray::InternalGet(int32_t index) {
+  Init();
+  return b_[index];
+}
+
+int32_t MemoryByteArray::InternalGet(int32_t index,
+                                     byte_t* b,
+                                     int32_t offset,
+                                     int32_t length) {
+  assert(b);
+  Init();
+  memcpy(b + offset, b_ + index, length);
+  return length;
+}
+
+void MemoryByteArray::Close() {
+  if (allocated_ && b_) {
+    delete[] b_;
+  }
+  b_ = NULL;
+}
+
+byte_t* MemoryByteArray::Begin() {
+  Init();
+  return b_;
+}
+
+}  // namespace sfntly
diff --git a/sfntly/data/memory_byte_array.h b/sfntly/data/memory_byte_array.h
new file mode 100644
index 0000000..838fd1a
--- /dev/null
+++ b/sfntly/data/memory_byte_array.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_DATA_MEMORY_BYTE_ARRAY_H_
+#define SFNTLY_CPP_SRC_SFNTLY_DATA_MEMORY_BYTE_ARRAY_H_
+
+#include "sfntly/data/byte_array.h"
+
+namespace sfntly {
+
+class MemoryByteArray : public ByteArray, public RefCounted<MemoryByteArray> {
+ public:
+  // Construct a new MemoryByteArray with a new array of the size given. It is
+  // assumed that none of the array is filled and readable.
+  explicit MemoryByteArray(int32_t length);
+
+  // Note: not implemented due to dangerous operations in constructor.
+  //explicit MemoryByteArray(ByteVector* b);
+
+  // Construct a new MemoryByteArray using byte array.
+  // @param b the byte array that provides the actual storage
+  // @param filled_length the index of the last byte in the array has data
+  // Note: This is different from Java version, it does not take over the
+  //       ownership of b.  Caller is responsible for handling the lifetime
+  //       of b.  C++ port also assumes filled_length is buffer_length since
+  //       there is not a reliable way to identify the actual size of buffer.
+  MemoryByteArray(byte_t* b, int32_t filled_length);
+
+  virtual ~MemoryByteArray();
+  virtual int32_t CopyTo(OutputStream* os, int32_t offset, int32_t length);
+
+  // Make gcc -Woverloaded-virtual happy.
+  virtual int32_t CopyTo(ByteArray* array) { return ByteArray::CopyTo(array); }
+  virtual int32_t CopyTo(ByteArray* array, int32_t offset, int32_t length) {
+    return ByteArray::CopyTo(array, offset, length);
+  }
+  virtual int32_t CopyTo(int32_t dst_offset,
+                         ByteArray* array,
+                         int32_t src_offset,
+                         int32_t length) {
+    return ByteArray::CopyTo(dst_offset, array, src_offset, length);
+  }
+  virtual int32_t CopyTo(OutputStream* os) { return ByteArray::CopyTo(os); }
+
+ protected:
+  virtual void InternalPut(int32_t index, byte_t b);
+  virtual int32_t InternalPut(int32_t index,
+                              byte_t* b,
+                              int32_t offset,
+                              int32_t length);
+  virtual byte_t InternalGet(int32_t index);
+  virtual int32_t InternalGet(int32_t index,
+                              byte_t* b,
+                              int32_t offset,
+                              int32_t length);
+  virtual void Close();
+  virtual byte_t* Begin();
+
+ private:
+  void Init();  // C++ port only, used to allocate memory outside constructor.
+
+  byte_t* b_;
+  bool allocated_;
+};
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_DATA_MEMORY_BYTE_ARRAY_H_
diff --git a/sfntly/data/readable_font_data.cc b/sfntly/data/readable_font_data.cc
new file mode 100644
index 0000000..06d783f
--- /dev/null
+++ b/sfntly/data/readable_font_data.cc
@@ -0,0 +1,336 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/data/readable_font_data.h"
+
+#include <stdio.h>
+
+#include "sfntly/data/memory_byte_array.h"
+#include "sfntly/data/writable_font_data.h"
+#include "sfntly/port/exception_type.h"
+
+namespace sfntly {
+
+ReadableFontData::ReadableFontData(ByteArray* array)
+    : FontData(array),
+      checksum_set_(false),
+      checksum_(0) {
+}
+
+ReadableFontData::~ReadableFontData() {}
+
+// TODO(arthurhsu): re-investigate the memory model of this function.  It's
+//                  not too useful without copying, but it's not performance
+//                  savvy to do copying.
+CALLER_ATTACH
+ReadableFontData* ReadableFontData::CreateReadableFontData(ByteVector* b) {
+  assert(b);
+  ByteArrayPtr ba = new MemoryByteArray(b->size());
+  ba->Put(0, b);
+  ReadableFontDataPtr wfd = new ReadableFontData(ba);
+  return wfd.Detach();
+}
+
+int64_t ReadableFontData::Checksum() {
+  AutoLock lock(checksum_lock_);
+  if (!checksum_set_) {
+    ComputeChecksum();
+  }
+  return checksum_;
+}
+
+void ReadableFontData::SetCheckSumRanges(const IntegerList& ranges) {
+  checksum_range_ = ranges;
+  checksum_set_ = false;  // UNIMPLEMENTED: atomicity
+}
+
+int32_t ReadableFontData::ReadUByte(int32_t index) {
+  int32_t b = array_->Get(BoundOffset(index));
+#if !defined (SFNTLY_NO_EXCEPTION)
+  if (b < 0) {
+    throw IndexOutOfBoundException(
+        "Index attempted to be read from is out of bounds", index);
+  }
+#endif
+  return b;
+}
+
+int32_t ReadableFontData::ReadByte(int32_t index) {
+  int32_t b = array_->Get(BoundOffset(index));
+#if !defined (SFNTLY_NO_EXCEPTION)
+  if (b < 0) {
+    throw IndexOutOfBoundException(
+        "Index attempted to be read from is out of bounds", index);
+  }
+#endif
+  return (b << 24) >> 24;
+}
+
+int32_t ReadableFontData::ReadBytes(int32_t index,
+                                    byte_t* b,
+                                    int32_t offset,
+                                    int32_t length) {
+  return array_->Get(BoundOffset(index), b, offset, BoundLength(index, length));
+}
+
+int32_t ReadableFontData::ReadChar(int32_t index) {
+  return ReadUByte(index);
+}
+
+int32_t ReadableFontData::ReadUShort(int32_t index) {
+  return 0xffff & (ReadUByte(index) << 8 | ReadUByte(index + 1));
+}
+
+int32_t ReadableFontData::ReadShort(int32_t index) {
+  return ((ReadByte(index) << 8 | ReadUByte(index + 1)) << 16) >> 16;
+}
+
+int32_t ReadableFontData::ReadUInt24(int32_t index) {
+  return 0xffffff & (ReadUByte(index) << 16 |
+                     ReadUByte(index + 1) << 8 |
+                     ReadUByte(index + 2));
+}
+
+int64_t ReadableFontData::ReadULong(int32_t index) {
+  return 0xffffffffL & (ReadUByte(index) << 24 |
+                        ReadUByte(index + 1) << 16 |
+                        ReadUByte(index + 2) << 8 |
+                        ReadUByte(index + 3));
+}
+
+int32_t ReadableFontData::ReadULongAsInt(int32_t index) {
+  int64_t ulong = ReadULong(index);
+#if !defined (SFNTLY_NO_EXCEPTION)
+  if ((ulong & 0x80000000) == 0x80000000) {
+    throw ArithmeticException("Long value too large to fit into an integer.");
+  }
+#endif
+  return static_cast<int32_t>(ulong);
+}
+
+int64_t ReadableFontData::ReadULongLE(int32_t index) {
+  return 0xffffffffL & (ReadUByte(index) |
+                        ReadUByte(index + 1) << 8 |
+                        ReadUByte(index + 2) << 16 |
+                        ReadUByte(index + 3) << 24);
+}
+
+int32_t ReadableFontData::ReadLong(int32_t index) {
+  return ReadByte(index) << 24 |
+         ReadUByte(index + 1) << 16 |
+         ReadUByte(index + 2) << 8 |
+         ReadUByte(index + 3);
+}
+
+int32_t ReadableFontData::ReadFixed(int32_t index) {
+  return ReadLong(index);
+}
+
+int64_t ReadableFontData::ReadDateTimeAsLong(int32_t index) {
+  return (int64_t)ReadULong(index) << 32 | ReadULong(index + 4);
+}
+
+int32_t ReadableFontData::ReadFWord(int32_t index) {
+  return ReadShort(index);
+}
+
+int32_t ReadableFontData::ReadFUFWord(int32_t index) {
+  return ReadUShort(index);
+}
+
+int32_t ReadableFontData::CopyTo(OutputStream* os) {
+  return array_->CopyTo(os, BoundOffset(0), Length());
+}
+
+int32_t ReadableFontData::CopyTo(WritableFontData* wfd) {
+  return array_->CopyTo(wfd->BoundOffset(0),
+                        wfd->array_,
+                        BoundOffset(0),
+                        Length());
+}
+
+int32_t ReadableFontData::CopyTo(ByteArray* ba) {
+  return array_->CopyTo(ba, BoundOffset(0), Length());
+}
+
+int32_t ReadableFontData::SearchUShort(int32_t start_index,
+                                       int32_t start_offset,
+                                       int32_t end_index,
+                                       int32_t end_offset,
+                                       int32_t length,
+                                       int32_t key) {
+  int32_t location = 0;
+  int32_t bottom = 0;
+  int32_t top = length;
+  while (top != bottom) {
+    location = (top + bottom) / 2;
+    int32_t location_start = ReadUShort(start_index + location * start_offset);
+    if (key < location_start) {
+      // location is below current location
+      top = location;
+    } else {
+      // is key below the upper bound?
+      int32_t location_end = ReadUShort(end_index + location * end_offset);
+#if defined (SFNTLY_DEBUG_FONTDATA)
+      fprintf(stderr, "**start: %d; end: %d\n", location_start, location_end);
+#endif
+      if (key <= location_end) {
+        return location;
+      } else {
+        // location is above the current location
+        bottom = location + 1;
+      }
+    }
+  }
+  return -1;
+}
+
+int32_t ReadableFontData::SearchUShort(int32_t start_index,
+                                       int32_t start_offset,
+                                       int32_t length,
+                                       int32_t key) {
+  int32_t location = 0;
+  int32_t bottom = 0;
+  int32_t top = length;
+  while (top != bottom) {
+    location = (top + bottom) / 2;
+    int32_t location_start = ReadUShort(start_index + location * start_offset);
+    if (key < location_start) {
+      // location is below current location
+      top = location;
+    } else if (key > location_start) {
+      // location is above current location
+      bottom = location + 1;
+    } else {
+      return location;
+    }
+  }
+  return -1;
+}
+
+int32_t ReadableFontData::SearchULong(int32_t start_index,
+                                      int32_t start_offset,
+                                      int32_t end_index,
+                                      int32_t end_offset,
+                                      int32_t length,
+                                      int32_t key) {
+  int32_t location = 0;
+  int32_t bottom = 0;
+  int32_t top = length;
+  while (top != bottom) {
+    location = (top + bottom) / 2;
+    int32_t location_start = ReadULongAsInt(start_index
+                                            + location * start_offset);
+    if (key < location_start) {
+      // location is below current location
+      top = location;
+    } else {
+      // is key below the upper bound?
+      int32_t location_end = ReadULongAsInt(end_index + location * end_offset);
+#if defined (SFNTLY_DEBUG_FONTDATA)
+      fprintf(stderr, "**start: %d; end: %d\n", location_start, location_end);
+#endif
+      if (key <= location_end) {
+        return location;
+      } else {
+        // location is above the current location
+        bottom = location + 1;
+      }
+    }
+  }
+  return -1;
+}
+
+CALLER_ATTACH FontData* ReadableFontData::Slice(int32_t offset,
+                                                int32_t length) {
+  if (offset < 0 || offset + length > Size()) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IndexOutOfBoundsException(
+        "Attempt to bind data outside of its limits");
+#endif
+    return NULL;
+  }
+  FontDataPtr slice = new ReadableFontData(this, offset, length);
+  return slice.Detach();
+}
+
+CALLER_ATTACH FontData* ReadableFontData::Slice(int32_t offset) {
+  if (offset < 0 || offset > Size()) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IndexOutOfBoundsException(
+        "Attempt to bind data outside of its limits");
+#endif
+    return NULL;
+  }
+  FontDataPtr slice = new ReadableFontData(this, offset);
+  return slice.Detach();
+}
+
+ReadableFontData::ReadableFontData(ReadableFontData* data, int32_t offset)
+    : FontData(data, offset),
+      checksum_set_(false),
+      checksum_(0) {
+}
+
+ReadableFontData::ReadableFontData(ReadableFontData* data,
+                                   int32_t offset,
+                                   int32_t length)
+    : FontData(data, offset, length),
+      checksum_set_(false),
+      checksum_(0) {
+}
+
+void ReadableFontData::ComputeChecksum() {
+  // TODO(arthurhsu): IMPLEMENT: synchronization/atomicity
+  int64_t sum = 0;
+  if (checksum_range_.empty()) {
+    sum = ComputeCheckSum(0, Length());
+  } else {
+    for (uint32_t low_bound_index = 0; low_bound_index < checksum_range_.size();
+         low_bound_index += 2) {
+      int32_t low_bound = checksum_range_[low_bound_index];
+      int32_t high_bound = (low_bound_index == checksum_range_.size() - 1) ?
+                                Length() :
+                                checksum_range_[low_bound_index + 1];
+      sum += ComputeCheckSum(low_bound, high_bound);
+    }
+  }
+
+  checksum_ = sum & 0xffffffffL;
+  checksum_set_ = true;
+}
+
+int64_t ReadableFontData::ComputeCheckSum(int32_t low_bound,
+                                          int32_t high_bound) {
+  int64_t sum = 0;
+  // Checksum all whole 4-byte chunks.
+  for (int32_t i = low_bound; i <= high_bound - 4; i += 4) {
+    sum += ReadULong(i);
+  }
+
+  // Add last fragment if not 4-byte multiple
+  int32_t off = high_bound & -4;
+  if (off < high_bound) {
+    int32_t b3 = ReadUByte(off);
+    int32_t b2 = (off + 1 < high_bound) ? ReadUByte(off + 1) : 0;
+    int32_t b1 = (off + 2 < high_bound) ? ReadUByte(off + 2) : 0;
+    int32_t b0 = 0;
+    sum += (b3 << 24) | (b2 << 16) | (b1 << 8) | b0;
+  }
+  return sum;
+}
+
+}  // namespace sfntly
diff --git a/sfntly/data/readable_font_data.h b/sfntly/data/readable_font_data.h
new file mode 100644
index 0000000..b43c626
--- /dev/null
+++ b/sfntly/data/readable_font_data.h
@@ -0,0 +1,308 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_DATA_READABLE_FONT_DATA_H_
+#define SFNTLY_CPP_SRC_SFNTLY_DATA_READABLE_FONT_DATA_H_
+
+#include "sfntly/data/font_data.h"
+#include "sfntly/port/lock.h"
+
+namespace sfntly {
+
+class WritableFontData;
+class OutputStream;
+
+// Writable font data wrapper. Supports reading of data primitives in the
+// TrueType / OpenType spec.
+// The data types used are as listed:
+// BYTE       8-bit unsigned integer.
+// CHAR       8-bit signed integer.
+// USHORT     16-bit unsigned integer.
+// SHORT      16-bit signed integer.
+// UINT24     24-bit unsigned integer.
+// ULONG      32-bit unsigned integer.
+// LONG       32-bit signed integer.
+// Fixed      32-bit signed fixed-point number (16.16)
+// FUNIT      Smallest measurable distance in the em space.
+// FWORD      16-bit signed integer (SHORT) that describes a quantity in FUnits.
+// UFWORD     16-bit unsigned integer (USHORT) that describes a quantity in
+//            FUnits.
+// F2DOT14    16-bit signed fixed number with the low 14 bits of fraction (2.14)
+// LONGDATETIME  Date represented in number of seconds since 12:00 midnight,
+//               January 1, 1904. The value is represented as a signed 64-bit
+//               integer.
+
+class ReadableFontData : public FontData,
+                         public RefCounted<ReadableFontData> {
+ public:
+  explicit ReadableFontData(ByteArray* array);
+  virtual ~ReadableFontData();
+
+  static CALLER_ATTACH ReadableFontData* CreateReadableFontData(ByteVector* b);
+
+  // Gets a computed checksum for the data. This checksum uses the OpenType spec
+  // calculation. Every ULong value (32 bit unsigned) in the data is summed and
+  // the resulting value is truncated to 32 bits. If the data length in bytes is
+  // not an integral multiple of 4 then any remaining bytes are treated as the
+  // start of a 4 byte sequence whose remaining bytes are zero.
+  // @return the checksum
+  int64_t Checksum();
+
+  // Sets the bounds to use for computing the checksum. These bounds are in
+  // begin and end pairs. If an odd number is given then the final range is
+  // assumed to extend to the end of the data. The lengths of each range must be
+  // a multiple of 4.
+  // @param ranges the range bounds to use for the checksum
+  void SetCheckSumRanges(const IntegerList& ranges);
+
+  // Read the UBYTE at the given index.
+  // @param index index into the font data
+  // @return the UBYTE; -1 if outside the bounds of the font data
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
+  virtual int32_t ReadUByte(int32_t index);
+
+  // Read the BYTE at the given index.
+  // @param index index into the font data
+  // @return the BYTE
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
+  virtual int32_t ReadByte(int32_t index);
+
+  // Read the bytes at the given index into the array.
+  // @param index index into the font data
+  // @param b the destination for the bytes read
+  // @param offset offset in the byte array to place the bytes
+  // @param length the length of bytes to read
+  // @return the number of bytes actually read; -1 if the index is outside the
+  //         bounds of the font data
+  virtual int32_t ReadBytes(int32_t index,
+                            byte_t* b,
+                            int32_t offset,
+                            int32_t length);
+
+  // Read the CHAR at the given index.
+  // @param index index into the font data
+  // @return the CHAR
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
+  virtual int32_t ReadChar(int32_t index);
+
+  // Read the USHORT at the given index.
+  // @param index index into the font data
+  // @return the USHORT
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
+  virtual int32_t ReadUShort(int32_t index);
+
+  // Read the SHORT at the given index.
+  // @param index index into the font data
+  // @return the SHORT
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
+  virtual int32_t ReadShort(int32_t index);
+
+  // Read the UINT24 at the given index.
+  // @param index index into the font data
+  // @return the UINT24
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
+  virtual int32_t ReadUInt24(int32_t index);
+
+  // Read the ULONG at the given index.
+  // @param index index into the font data
+  // @return the ULONG
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
+  virtual int64_t ReadULong(int32_t index);
+
+  // Read the ULONG at the given index as int32_t.
+  // @param index index into the font data
+  // @return the ULONG
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
+  virtual int32_t ReadULongAsInt(int32_t index);
+
+  // Read the ULONG at the given index, little-endian variant
+  // @param index index into the font data
+  // @return the ULONG
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
+  virtual int64_t ReadULongLE(int32_t index);
+
+  // Read the LONG at the given index.
+  // @param index index into the font data
+  // @return the LONG
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
+  virtual int32_t ReadLong(int32_t index);
+
+  // Read the Fixed at the given index.
+  // @param index index into the font data
+  // @return the Fixed
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
+  virtual int32_t ReadFixed(int32_t index);
+
+  // Read the LONGDATETIME at the given index.
+  // @param index index into the font data
+  // @return the LONGDATETIME
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
+  virtual int64_t ReadDateTimeAsLong(int32_t index);
+
+  // Read the FWORD at the given index.
+  // @param index index into the font data
+  // @return the FWORD
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
+  virtual int32_t ReadFWord(int32_t index);
+
+  // Read the UFWORD at the given index.
+  // @param index index into the font data
+  // @return the UFWORD
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
+  virtual int32_t ReadFUFWord(int32_t index);
+
+  // Note: Not ported because they just throw UnsupportedOperationException()
+  //       in Java.
+  /*
+  virtual int32_t ReadFUnit(int32_t index);
+  virtual int64_t ReadF2Dot14(int32_t index);
+  */
+
+  // Copy the FontData to an OutputStream.
+  // @param os the destination
+  // @return number of bytes copied
+  // @throws IOException
+  virtual int32_t CopyTo(OutputStream* os);
+
+  // Copy the FontData to a WritableFontData.
+  // @param wfd the destination
+  // @return number of bytes copied
+  // @throws IOException
+  virtual int32_t CopyTo(WritableFontData* wfd);
+
+  // Make gcc -Woverloaded-virtual happy.
+  virtual int32_t CopyTo(ByteArray* ba);
+
+  // Search for the key value in the range tables provided.
+  // The search looks through the start-end pairs looking for the key value. It
+  // is assumed that the start-end pairs are both represented by UShort values,
+  // ranges do not overlap, and are monotonically increasing.
+  // @param startIndex the position to read the first start value from
+  // @param startOffset the offset between subsequent start values
+  // @param endIndex the position to read the first end value from
+  // @param endOffset the offset between subsequent end values
+  // @param length the number of start-end pairs
+  // @param key the value to search for
+  // @return the index of the start-end pairs in which the key was found; -1
+  //         otherwise
+  int32_t SearchUShort(int32_t start_index,
+                       int32_t start_offset,
+                       int32_t end_index,
+                       int32_t end_offset,
+                       int32_t length,
+                       int32_t key);
+
+  // Search for the key value in the table provided.
+  // The search looks through the values looking for the key value. It is
+  // assumed that the are represented by UShort values and are monotonically
+  // increasing.
+  // @param startIndex the position to read the first start value from
+  // @param startOffset the offset between subsequent start values
+  // @param length the number of start-end pairs
+  // @param key the value to search for
+  // @return the index of the start-end pairs in which the key was found; -1
+  //         otherwise
+  int32_t SearchUShort(int32_t start_index,
+                       int32_t start_offset,
+                       int32_t length,
+                       int32_t key);
+
+  // Search for the key value in the range tables provided.
+  // The search looks through the start-end pairs looking for the key value. It
+  // is assumed that the start-end pairs are both represented by ULong values
+  // that can be represented within 31 bits, ranges do not overlap, and are
+  // monotonically increasing.
+  // @param startIndex the position to read the first start value from
+  // @param startOffset the offset between subsequent start values
+  // @param endIndex the position to read the first end value from
+  // @param endOffset the offset between subsequent end values
+  // @param length the number of start-end pairs
+  // @param key the value to search for
+  // @return the index of the start-end pairs in which the key was found; -1
+  //         otherwise
+  int32_t SearchULong(int32_t start_index,
+                      int32_t start_offset,
+                      int32_t end_index,
+                      int32_t end_offset,
+                      int32_t length,
+                      int32_t key);
+
+
+  // TODO(arthurhsu): IMPLEMENT
+  /*
+  virtual int32_t ReadFUnit(int32_t index);
+  virtual int64_t ReadF2Dot14(int32_t index);
+  virtual int64_t ReadLongDateTime(int32_t index);
+  */
+
+  // Makes a slice of this FontData. The returned slice will share the data with
+  // the original FontData.
+  // @param offset the start of the slice
+  // @param length the number of bytes in the slice
+  // @return a slice of the original FontData
+  // Note: C++ polymorphism requires return type to be consistent
+  virtual CALLER_ATTACH FontData* Slice(int32_t offset, int32_t length);
+
+  // Makes a bottom bound only slice of this array. The returned slice will
+  // share the data with the original FontData.
+  // @param offset the start of the slice
+  // @return a slice of the original FontData
+  // Note: C++ polymorphism requires return type to be consistent
+  virtual CALLER_ATTACH FontData* Slice(int32_t offset);
+
+  // Not Ported: toString()
+
+ protected:
+  // Constructor. Creates a bounded wrapper of another ReadableFontData from the
+  // given offset until the end of the original ReadableFontData.
+  // @param data data to wrap
+  // @param offset the start of this data's view of the original data
+  ReadableFontData(ReadableFontData* data, int32_t offset);
+
+  // Constructor. Creates a bounded wrapper of another ReadableFontData from the
+  // given offset until the end of the original ReadableFontData.
+  // @param data data to wrap
+  // @param offset the start of this data's view of the original data
+  // @param length the length of the other FontData to use
+  ReadableFontData(ReadableFontData* data, int32_t offset, int32_t length);
+
+ private:
+  // Compute the checksum for the font data using any ranges set for the
+  // calculation.
+  void ComputeChecksum();
+
+  // Do the actual computation of the checksum for a range using the
+  // TrueType/OpenType checksum algorithm. The range used is from the low bound
+  // to the high bound in steps of four bytes. If any of the bytes within that 4
+  // byte segment are not readable then it will considered a zero for
+  // calculation.
+  // Only called from within a synchronized method so it does not need to be
+  // synchronized itself.
+  // @param lowBound first position to start a 4 byte segment on
+  // @param highBound last possible position to start a 4 byte segment on
+  // @return the checksum for the total range
+  int64_t ComputeCheckSum(int32_t low_bound, int32_t high_bound);
+
+  Lock checksum_lock_;
+  bool checksum_set_;
+  int64_t checksum_;
+  IntegerList checksum_range_;
+};
+typedef Ptr<ReadableFontData> ReadableFontDataPtr;
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_DATA_READABLE_FONT_DATA_H_
diff --git a/sfntly/data/writable_font_data.cc b/sfntly/data/writable_font_data.cc
new file mode 100644
index 0000000..4b3b440
--- /dev/null
+++ b/sfntly/data/writable_font_data.cc
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/data/writable_font_data.h"
+
+#include <algorithm>
+
+#include "sfntly/data/memory_byte_array.h"
+#include "sfntly/data/growable_memory_byte_array.h"
+
+namespace sfntly {
+
+WritableFontData::WritableFontData(ByteArray* ba) : ReadableFontData(ba) {
+}
+
+WritableFontData::~WritableFontData() {}
+
+// static
+CALLER_ATTACH
+WritableFontData* WritableFontData::CreateWritableFontData(int32_t length) {
+  ByteArrayPtr ba;
+  if (length > 0) {
+    ba = new MemoryByteArray(length);
+    ba->SetFilledLength(length);
+  } else {
+    ba = new GrowableMemoryByteArray();
+  }
+  WritableFontDataPtr wfd = new WritableFontData(ba);
+  return wfd.Detach();
+}
+
+// TODO(arthurhsu): re-investigate the memory model of this function.  It's
+//                  not too useful without copying, but it's not performance
+//                  savvy to do copying.
+CALLER_ATTACH
+WritableFontData* WritableFontData::CreateWritableFontData(ByteVector* b) {
+  ByteArrayPtr ba = new GrowableMemoryByteArray();
+  ba->Put(0, b);
+  WritableFontDataPtr wfd = new WritableFontData(ba);
+  return wfd.Detach();
+}
+
+int32_t WritableFontData::WriteByte(int32_t index, byte_t b) {
+  array_->Put(BoundOffset(index), b);
+  return 1;
+}
+
+int32_t WritableFontData::WriteBytes(int32_t index,
+                                     byte_t* b,
+                                     int32_t offset,
+                                     int32_t length) {
+  return array_->Put(BoundOffset(index),
+                     b,
+                     offset,
+                     BoundLength(index, length));
+}
+
+int32_t WritableFontData::WriteBytes(int32_t index, ByteVector* b) {
+  assert(b);
+  return WriteBytes(index, &((*b)[0]), 0, b->size());
+}
+
+int32_t WritableFontData::WriteBytesPad(int32_t index,
+                                        ByteVector* b,
+                                        int32_t offset,
+                                        int32_t length,
+                                        byte_t pad) {
+  int32_t written =
+      array_->Put(BoundOffset(index),
+                  &((*b)[0]),
+                  offset,
+                  BoundLength(index,
+                              std::min<int32_t>(length, b->size() - offset)));
+  written += WritePadding(written + index, length - written, pad);
+  return written;
+}
+
+int32_t WritableFontData::WritePadding(int32_t index, int32_t count) {
+  return WritePadding(index, count, (byte_t)0);
+}
+
+int32_t WritableFontData::WritePadding(int32_t index, int32_t count,
+                                       byte_t pad) {
+  for (int32_t i = 0; i < count; ++i) {
+    array_->Put(index + i, pad);
+  }
+  return count;
+}
+
+int32_t WritableFontData::WriteChar(int32_t index, byte_t c) {
+  return WriteByte(index, c);
+}
+
+int32_t WritableFontData::WriteUShort(int32_t index, int32_t us) {
+  WriteByte(index, (byte_t)((us >> 8) & 0xff));
+  WriteByte(index + 1, (byte_t)(us & 0xff));
+  return 2;
+}
+
+int32_t WritableFontData::WriteUShortLE(int32_t index, int32_t us) {
+  WriteByte(index, (byte_t)(us & 0xff));
+  WriteByte(index + 1, (byte_t)((us >> 8) & 0xff));
+  return 2;
+}
+
+int32_t WritableFontData::WriteShort(int32_t index, int32_t s) {
+  return WriteUShort(index, s);
+}
+
+int32_t WritableFontData::WriteUInt24(int32_t index, int32_t ui) {
+  WriteByte(index, (byte_t)((ui >> 16) & 0xff));
+  WriteByte(index + 1, (byte_t)((ui >> 8) & 0xff));
+  WriteByte(index + 2, (byte_t)(ui & 0xff));
+  return 3;
+}
+
+int32_t WritableFontData::WriteULong(int32_t index, int64_t ul) {
+  WriteByte(index, (byte_t)((ul >> 24) & 0xff));
+  WriteByte(index + 1, (byte_t)((ul >> 16) & 0xff));
+  WriteByte(index + 2, (byte_t)((ul >> 8) & 0xff));
+  WriteByte(index + 3, (byte_t)(ul & 0xff));
+  return 4;
+}
+
+int32_t WritableFontData::WriteULongLE(int32_t index, int64_t ul) {
+  WriteByte(index, (byte_t)(ul & 0xff));
+  WriteByte(index + 1, (byte_t)((ul >> 8) & 0xff));
+  WriteByte(index + 2, (byte_t)((ul >> 16) & 0xff));
+  WriteByte(index + 3, (byte_t)((ul >> 24) & 0xff));
+  return 4;
+}
+
+int32_t WritableFontData::WriteLong(int32_t index, int64_t l) {
+  return WriteULong(index, l);
+}
+
+int32_t WritableFontData::WriteFixed(int32_t index, int32_t f) {
+  return WriteLong(index, f);
+}
+
+int32_t WritableFontData::WriteDateTime(int32_t index, int64_t date) {
+  WriteULong(index, (date >> 32) & 0xffffffff);
+  WriteULong(index + 4, date & 0xffffffff);
+  return 8;
+}
+
+void WritableFontData::CopyFrom(InputStream* is, int32_t length) {
+  array_->CopyFrom(is, length);
+}
+
+void WritableFontData::CopyFrom(InputStream* is) {
+  array_->CopyFrom(is);
+}
+
+CALLER_ATTACH FontData* WritableFontData::Slice(int32_t offset,
+                                                int32_t length) {
+  if (offset < 0 || offset + length > Size()) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IndexOutOfBoundsException(
+        "Attempt to bind data outside of its limits");
+#endif
+    return NULL;
+  }
+  FontDataPtr slice = new WritableFontData(this, offset, length);
+  return slice.Detach();
+}
+
+CALLER_ATTACH FontData* WritableFontData::Slice(int32_t offset) {
+  if (offset > Size()) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IndexOutOfBoundsException(
+        "Attempt to bind data outside of its limits");
+#endif
+    return NULL;
+  }
+  FontDataPtr slice = new WritableFontData(this, offset);
+  return slice.Detach();
+}
+
+WritableFontData::WritableFontData(WritableFontData* data, int32_t offset)
+    : ReadableFontData(data, offset) {
+}
+
+WritableFontData::WritableFontData(WritableFontData* data,
+                                   int32_t offset,
+                                   int32_t length)
+    : ReadableFontData(data, offset, length) {
+}
+
+}  // namespace sfntly
diff --git a/sfntly/data/writable_font_data.h b/sfntly/data/writable_font_data.h
new file mode 100644
index 0000000..d2a049e
--- /dev/null
+++ b/sfntly/data/writable_font_data.h
@@ -0,0 +1,211 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_DATA_WRITABLE_FONT_DATA_H_
+#define SFNTLY_CPP_SRC_SFNTLY_DATA_WRITABLE_FONT_DATA_H_
+
+#include "sfntly/data/readable_font_data.h"
+
+namespace sfntly {
+
+// Writable font data wrapper. Supports writing of data primitives in the
+// TrueType / OpenType spec.
+class WritableFontData : public ReadableFontData {
+ public:
+  explicit WritableFontData(ByteArray* ba);
+  virtual ~WritableFontData();
+
+  // Constructs a writable font data object. If the length is specified as
+  // positive then a fixed size font data object will be created. If the length
+  // is zero or less then a growable font data object will be created and the
+  // size will be used as an estimate to help in allocating the original space.
+  // @param length if length > 0 create a fixed length font data; otherwise
+  //        create a growable font data
+  // @return a new writable font data
+  static CALLER_ATTACH WritableFontData* CreateWritableFontData(int32_t length);
+
+  // Constructs a writable font data object. The new font data object will wrap
+  // the bytes passed in to the factory and it will take make a copy of those
+  // bytes.
+  // @param b the byte vector to wrap
+  // @return a new writable font data
+  static CALLER_ATTACH WritableFontData* CreateWritableFontData(ByteVector* b);
+
+  // Write a byte at the given index.
+  // @param index index into the font data
+  // @param b the byte to write
+  // @return the number of bytes written
+  virtual int32_t WriteByte(int32_t index, byte_t b);
+
+  // Write the bytes from the array.
+  // @param index index into the font data
+  // @param b the source for the bytes to be written
+  // @param offset offset in the byte array
+  // @param length the length of the bytes to be written
+  // @return the number of bytes actually written; -1 if the index is outside
+  //         the FontData's range
+  virtual int32_t WriteBytes(int32_t index,
+                             byte_t* b,
+                             int32_t offset,
+                             int32_t length);
+
+  // Write the bytes from the array.
+  // @param index index into the font data
+  // @param b the source for the bytes to be written
+  // @return the number of bytes actually written; -1 if the index is outside
+  //         the FontData's range
+  virtual int32_t WriteBytes(int32_t index, ByteVector* b);
+
+  // Write the bytes from the array and pad if necessary.
+  // Write to the length given using the byte array provided and if there are
+  // not enough bytes in the array then pad to the requested length using the
+  // pad byte specified.
+  // @param index index into the font data
+  // @param b the source for the bytes to be written
+  // @param offset offset in the byte array
+  // @param length the length of the bytes to be written
+  // @param pad the padding byte to be used if necessary
+  // @return the number of bytes actually written
+  virtual int32_t WriteBytesPad(int32_t index,
+                                ByteVector* b,
+                                int32_t offset,
+                                int32_t length,
+                                byte_t pad);
+
+  // Writes padding to the FontData. The padding byte written is 0x00.
+  // @param index index into the font data
+  // @param count the number of pad bytes to write
+  // @return the number of pad bytes written
+  virtual int32_t WritePadding(int32_t index, int32_t count);
+
+  // Writes padding to the FontData.
+  // @param index index into the font data
+  // @param count the number of pad bytes to write
+  // @param pad the byte value to use as padding
+  // @return the number of pad bytes written
+  virtual int32_t WritePadding(int32_t index, int32_t count, byte_t pad);
+
+  // Write the CHAR at the given index.
+  // @param index index into the font data
+  // @param c the CHAR
+  // @return the number of bytes actually written
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
+  virtual int32_t WriteChar(int32_t index, byte_t c);
+
+  // Write the USHORT at the given index.
+  // @param index index into the font data
+  // @param us the USHORT
+  // @return the number of bytes actually written
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
+  virtual int32_t WriteUShort(int32_t index, int32_t us);
+
+  // Write the USHORT at the given index in little endian format.
+  // @param index index into the font data
+  // @param us the USHORT
+  // @return the number of bytes actually written
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
+  virtual int32_t WriteUShortLE(int32_t index, int32_t us);
+
+  // Write the SHORT at the given index.
+  // @param index index into the font data
+  // @param s the SHORT
+  // @return the number of bytes actually written
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
+  virtual int32_t WriteShort(int32_t index, int32_t s);
+
+  // Write the UINT24 at the given index.
+  // @param index index into the font data
+  // @param ui the UINT24
+  // @return the number of bytes actually written
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
+  virtual int32_t WriteUInt24(int32_t index, int32_t ui);
+
+  // Write the ULONG at the given index.
+  // @param index index into the font data
+  // @param ul the ULONG
+  // @return the number of bytes actually written
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
+  virtual int32_t WriteULong(int32_t index, int64_t ul);
+
+  // Write the ULONG at the given index in little endian format.
+  // @param index index into the font data
+  // @param ul the ULONG
+  // @return the number of bytes actually written
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
+  virtual int32_t WriteULongLE(int32_t index, int64_t ul);
+
+  // Write the LONG at the given index.
+  // @param index index into the font data
+  // @param l the LONG
+  // @return the number of bytes actually written
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
+  virtual int32_t WriteLong(int32_t index, int64_t l);
+
+  // Write the Fixed at the given index.
+  // @param index index into the font data
+  // @param f the Fixed
+  // @return the number of bytes actually written
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
+  virtual int32_t WriteFixed(int32_t index, int32_t f);
+
+  // Write the LONGDATETIME at the given index.
+  // @param index index into the font data
+  // @param date the LONGDATETIME
+  // @return the number of bytes actually written
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
+  virtual int32_t WriteDateTime(int32_t index, int64_t date);
+
+  // Copy from the InputStream into this FontData.
+  // @param is the source
+  // @param length the number of bytes to copy
+  // @throws IOException
+  virtual void CopyFrom(InputStream* is, int32_t length);
+
+  // Copy everything from the InputStream into this FontData.
+  // @param is the source
+  // @throws IOException
+  virtual void CopyFrom(InputStream* is);
+
+  // Makes a slice of this FontData. The returned slice will share the data with
+  // the original FontData.
+  // @param offset the start of the slice
+  // @param length the number of bytes in the slice
+  // @return a slice of the original FontData
+  virtual CALLER_ATTACH FontData* Slice(int32_t offset, int32_t length);
+
+  // Makes a bottom bound only slice of this array. The returned slice will
+  // share the data with the original FontData.
+  // @param offset the start of the slice
+  // @return a slice of the original FontData
+  virtual CALLER_ATTACH FontData* Slice(int32_t offset);
+
+ private:
+  // Constructor with a lower bound.
+  // @param data other WritableFontData object to share data with
+  // @param offset offset from the other WritableFontData's data
+  WritableFontData(WritableFontData* data, int32_t offset);
+
+  // Constructor with lower bound and a length bound.
+  // @param data other WritableFontData object to share data with
+  // @param offset offset from the other WritableFontData's data
+  // @param length length of other WritableFontData's data to use
+  WritableFontData(WritableFontData* data, int32_t offset, int32_t length);
+};
+typedef Ptr<WritableFontData> WritableFontDataPtr;
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_DATA_WRITABLE_FONT_DATA_H_
diff --git a/sfntly/font.cc b/sfntly/font.cc
new file mode 100644
index 0000000..347e0c1
--- /dev/null
+++ b/sfntly/font.cc
@@ -0,0 +1,557 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/font.h"
+
+#include <stdio.h>
+
+#include <functional>
+#include <algorithm>
+#include <map>
+#include <string>
+#include <typeinfo>
+#include <iterator>
+
+#include "sfntly/data/font_input_stream.h"
+#include "sfntly/font_factory.h"
+#include "sfntly/math/fixed1616.h"
+#include "sfntly/math/font_math.h"
+#include "sfntly/port/exception_type.h"
+#include "sfntly/table/core/font_header_table.h"
+#include "sfntly/table/core/horizontal_device_metrics_table.h"
+#include "sfntly/table/core/horizontal_header_table.h"
+#include "sfntly/table/core/horizontal_metrics_table.h"
+#include "sfntly/table/core/maximum_profile_table.h"
+#include "sfntly/table/truetype/loca_table.h"
+#include "sfntly/tag.h"
+
+namespace sfntly {
+
+const int32_t SFNTVERSION_MAJOR = 1;
+const int32_t SFNTVERSION_MINOR = 0;
+
+/******************************************************************************
+ * Font class
+ ******************************************************************************/
+Font::~Font() {}
+
+bool Font::HasTable(int32_t tag) {
+  TableMap::const_iterator result = tables_.find(tag);
+  TableMap::const_iterator end = tables_.end();
+  return (result != end);
+}
+
+Table* Font::GetTable(int32_t tag) {
+  if (!HasTable(tag)) {
+    return NULL;
+  }
+  return tables_[tag];
+}
+
+const TableMap* Font::GetTableMap() {
+  return &tables_;
+}
+
+void Font::Serialize(OutputStream* os, IntegerList* table_ordering) {
+  assert(table_ordering);
+  IntegerList final_table_ordering;
+  GenerateTableOrdering(table_ordering, &final_table_ordering);
+  TableHeaderList table_records;
+  BuildTableHeadersForSerialization(&final_table_ordering, &table_records);
+
+  FontOutputStream fos(os);
+  SerializeHeader(&fos, &table_records);
+  SerializeTables(&fos, &table_records);
+}
+
+Font::Font(int32_t sfnt_version, ByteVector* digest)
+    : sfnt_version_(sfnt_version) {
+  // non-trivial assignments that makes debugging hard if placed in
+  // initialization list
+  digest_ = *digest;
+}
+
+void Font::BuildTableHeadersForSerialization(IntegerList* table_ordering,
+                                             TableHeaderList* table_headers) {
+  assert(table_headers);
+  assert(table_ordering);
+
+  IntegerList final_table_ordering;
+  GenerateTableOrdering(table_ordering, &final_table_ordering);
+  int32_t table_offset = Offset::kTableRecordBegin + num_tables() *
+                         Offset::kTableRecordSize;
+  for (IntegerList::iterator tag = final_table_ordering.begin(),
+                             tag_end = final_table_ordering.end();
+                             tag != tag_end; ++tag) {
+    if (tables_.find(*tag) == tables_.end()) {
+      continue;
+    }
+    TablePtr table = tables_[*tag];
+    if (table != NULL) {
+      HeaderPtr header =
+          new Header(*tag, table->CalculatedChecksum(), table_offset,
+                     table->header()->length());
+      table_headers->push_back(header);
+      table_offset += (table->DataLength() + 3) & ~3;
+    }
+  }
+}
+
+void Font::SerializeHeader(FontOutputStream* fos,
+                           TableHeaderList* table_headers) {
+  fos->WriteFixed(sfnt_version_);
+  fos->WriteUShort(table_headers->size());
+  int32_t log2_of_max_power_of_2 = FontMath::Log2(table_headers->size());
+  int32_t search_range = 2 << (log2_of_max_power_of_2 - 1 + 4);
+  fos->WriteUShort(search_range);
+  fos->WriteUShort(log2_of_max_power_of_2);
+  fos->WriteUShort((table_headers->size() * 16) - search_range);
+
+  HeaderTagSortedSet sorted_headers;
+  std::copy(table_headers->begin(),
+            table_headers->end(),
+            std::inserter(sorted_headers, sorted_headers.end()));
+
+  for (HeaderTagSortedSet::iterator record = sorted_headers.begin(),
+                                    record_end = sorted_headers.end();
+                                    record != record_end; ++record) {
+    fos->WriteULong((*record)->tag());
+    fos->WriteULong((int32_t)((*record)->checksum()));
+    fos->WriteULong((*record)->offset());
+    fos->WriteULong((*record)->length());
+  }
+}
+
+void Font::SerializeTables(FontOutputStream* fos,
+                           TableHeaderList* table_headers) {
+  assert(fos);
+  assert(table_headers);
+  for (TableHeaderList::iterator record = table_headers->begin(),
+                                 end_of_headers = table_headers->end();
+                                 record != end_of_headers; ++record) {
+    TablePtr target_table = GetTable((*record)->tag());
+    if (target_table == NULL) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+      throw IOException("Table out of sync with font header.");
+#endif
+      return;
+    }
+    int32_t table_size = target_table->Serialize(fos);
+    if (table_size != (*record)->length()) {
+      assert(false);
+    }
+    int32_t filler_size = ((table_size + 3) & ~3) - table_size;
+    for (int32_t i = 0; i < filler_size; ++i) {
+      fos->Write(static_cast<byte_t>(0));
+    }
+  }
+}
+
+void Font::GenerateTableOrdering(IntegerList* default_table_ordering,
+                                 IntegerList* table_ordering) {
+  assert(default_table_ordering);
+  assert(table_ordering);
+  table_ordering->clear();
+  if (default_table_ordering->empty()) {
+    DefaultTableOrdering(default_table_ordering);
+  }
+
+  typedef std::map<int32_t, bool> Int2Bool;
+  typedef std::pair<int32_t, bool> Int2BoolEntry;
+  Int2Bool tables_in_font;
+  for (TableMap::iterator table = tables_.begin(), table_end = tables_.end();
+                          table != table_end; ++table) {
+    tables_in_font.insert(Int2BoolEntry(table->first, false));
+  }
+  for (IntegerList::iterator tag = default_table_ordering->begin(),
+                             tag_end = default_table_ordering->end();
+                             tag != tag_end; ++tag) {
+    if (HasTable(*tag)) {
+      table_ordering->push_back(*tag);
+      tables_in_font[*tag] = true;
+    }
+  }
+  for (Int2Bool::iterator table = tables_in_font.begin(),
+                          table_end = tables_in_font.end();
+                          table != table_end; ++table) {
+    if (table->second == false)
+      table_ordering->push_back(table->first);
+  }
+}
+
+void Font::DefaultTableOrdering(IntegerList* default_table_ordering) {
+  assert(default_table_ordering);
+  default_table_ordering->clear();
+  if (HasTable(Tag::CFF)) {
+    default_table_ordering->resize(CFF_TABLE_ORDERING_SIZE);
+    std::copy(CFF_TABLE_ORDERING, CFF_TABLE_ORDERING + CFF_TABLE_ORDERING_SIZE,
+              default_table_ordering->begin());
+    return;
+  }
+  default_table_ordering->resize(TRUE_TYPE_TABLE_ORDERING_SIZE);
+  std::copy(TRUE_TYPE_TABLE_ORDERING,
+            TRUE_TYPE_TABLE_ORDERING + TRUE_TYPE_TABLE_ORDERING_SIZE,
+            default_table_ordering->begin());
+}
+
+/******************************************************************************
+ * Font::Builder class
+ ******************************************************************************/
+Font::Builder::~Builder() {}
+
+CALLER_ATTACH Font::Builder* Font::Builder::GetOTFBuilder(FontFactory* factory,
+                                                          InputStream* is) {
+  FontBuilderPtr builder = new Builder(factory);
+  builder->LoadFont(is);
+  return builder.Detach();
+}
+
+CALLER_ATTACH Font::Builder* Font::Builder::GetOTFBuilder(
+    FontFactory* factory,
+    WritableFontData* wfd,
+    int32_t offset_to_offset_table) {
+  FontBuilderPtr builder = new Builder(factory);
+  builder->LoadFont(wfd, offset_to_offset_table);
+  return builder.Detach();
+}
+
+CALLER_ATTACH Font::Builder* Font::Builder::GetOTFBuilder(
+    FontFactory* factory) {
+  FontBuilderPtr builder = new Builder(factory);
+  return builder.Detach();
+}
+
+bool Font::Builder::ReadyToBuild() {
+  // just read in data with no manipulation
+  if (table_builders_.empty() && !data_blocks_.empty()) {
+    return true;
+  }
+
+  // TODO(stuartg): font level checks - required tables etc?
+  for (TableBuilderMap::iterator table_builder = table_builders_.begin(),
+                                 table_builder_end = table_builders_.end();
+                                 table_builder != table_builder_end;
+                                 ++table_builder) {
+    if (!table_builder->second->ReadyToBuild())
+      return false;
+  }
+  return true;
+}
+
+CALLER_ATTACH Font* Font::Builder::Build() {
+  FontPtr font = new Font(sfnt_version_, &digest_);
+
+  if (!table_builders_.empty()) {
+    // Note: Different from Java. Directly use font->tables_ here to avoid
+    //       STL container copying.
+    BuildTablesFromBuilders(font, &table_builders_, &font->tables_);
+  }
+
+  table_builders_.clear();
+  data_blocks_.clear();
+  return font.Detach();
+}
+
+void Font::Builder::SetDigest(ByteVector* digest) {
+  digest_.clear();
+  digest_ = *digest;
+}
+
+void Font::Builder::ClearTableBuilders() {
+  table_builders_.clear();
+}
+
+bool Font::Builder::HasTableBuilder(int32_t tag) {
+  return (table_builders_.find(tag) != table_builders_.end());
+}
+
+Table::Builder* Font::Builder::GetTableBuilder(int32_t tag) {
+  if (HasTableBuilder(tag))
+    return table_builders_[tag];
+  return NULL;
+}
+
+Table::Builder* Font::Builder::NewTableBuilder(int32_t tag) {
+  HeaderPtr header = new Header(tag);
+  TableBuilderPtr builder;
+  builder.Attach(Table::Builder::GetBuilder(header, NULL));
+  table_builders_.insert(TableBuilderEntry(header->tag(), builder));
+  return builder;
+}
+
+Table::Builder* Font::Builder::NewTableBuilder(int32_t tag,
+                                               ReadableFontData* src_data) {
+  assert(src_data);
+  WritableFontDataPtr data;
+  data.Attach(WritableFontData::CreateWritableFontData(src_data->Length()));
+  // TODO(stuarg): take over original data instead?
+  src_data->CopyTo(data);
+
+  HeaderPtr header = new Header(tag, data->Length());
+  TableBuilderPtr builder;
+  builder.Attach(Table::Builder::GetBuilder(header, data));
+  table_builders_.insert(TableBuilderEntry(tag, builder));
+  return builder;
+}
+
+void Font::Builder::RemoveTableBuilder(int32_t tag) {
+  TableBuilderMap::iterator target = table_builders_.find(tag);
+  if (target != table_builders_.end()) {
+    table_builders_.erase(target);
+  }
+}
+
+Font::Builder::Builder(FontFactory* factory)
+    : factory_(factory),
+      sfnt_version_(Fixed1616::Fixed(SFNTVERSION_MAJOR, SFNTVERSION_MINOR)) {
+}
+
+void Font::Builder::LoadFont(InputStream* is) {
+  // Note: we do not throw exception here for is.  This is more of an assertion.
+  assert(is);
+  FontInputStream font_is(is);
+  HeaderOffsetSortedSet records;
+  ReadHeader(&font_is, &records);
+  LoadTableData(&records, &font_is, &data_blocks_);
+  BuildAllTableBuilders(&data_blocks_, &table_builders_);
+  font_is.Close();
+}
+
+void Font::Builder::LoadFont(WritableFontData* wfd,
+                             int32_t offset_to_offset_table) {
+  // Note: we do not throw exception here for is.  This is more of an assertion.
+  assert(wfd);
+  HeaderOffsetSortedSet records;
+  ReadHeader(wfd, offset_to_offset_table, &records);
+  LoadTableData(&records, wfd, &data_blocks_);
+  BuildAllTableBuilders(&data_blocks_, &table_builders_);
+}
+
+int32_t Font::Builder::SfntWrapperSize() {
+  return Offset::kSfntHeaderSize +
+         (Offset::kTableRecordSize * table_builders_.size());
+}
+
+void Font::Builder::BuildAllTableBuilders(DataBlockMap* table_data,
+                                          TableBuilderMap* builder_map) {
+  for (DataBlockMap::iterator record = table_data->begin(),
+                              record_end = table_data->end();
+                              record != record_end; ++record) {
+    TableBuilderPtr builder;
+    builder.Attach(GetTableBuilder(record->first.p_, record->second.p_));
+    builder_map->insert(TableBuilderEntry(record->first->tag(), builder));
+  }
+  InterRelateBuilders(&table_builders_);
+}
+
+CALLER_ATTACH
+Table::Builder* Font::Builder::GetTableBuilder(Header* header,
+                                               WritableFontData* data) {
+  return Table::Builder::GetBuilder(header, data);
+}
+
+void Font::Builder::BuildTablesFromBuilders(Font* font,
+                                            TableBuilderMap* builder_map,
+                                            TableMap* table_map) {
+  UNREFERENCED_PARAMETER(font);
+  InterRelateBuilders(builder_map);
+
+  // Now build all the tables.
+  for (TableBuilderMap::iterator builder = builder_map->begin(),
+                                 builder_end = builder_map->end();
+                                 builder != builder_end; ++builder) {
+    TablePtr table;
+    if (builder->second && builder->second->ReadyToBuild()) {
+      table.Attach(down_cast<Table*>(builder->second->Build()));
+    }
+    if (table == NULL) {
+      table_map->clear();
+#if !defined (SFNTLY_NO_EXCEPTION)
+      std::string builder_string = "Unable to build table - ";
+      char* table_name = TagToString(builder->first);
+      builder_string += table_name;
+      delete[] table_name;
+      throw RuntimeException(builder_string.c_str());
+#endif
+      return;
+    }
+    table_map->insert(TableMapEntry(table->header()->tag(), table));
+  }
+}
+
+static Table::Builder* GetBuilder(TableBuilderMap* builder_map, int32_t tag) {
+  if (builder_map) {
+    TableBuilderMap::iterator target = builder_map->find(tag);
+    if (target != builder_map->end()) {
+      return target->second.p_;
+    }
+  }
+
+  return NULL;
+}
+
+void Font::Builder::InterRelateBuilders(TableBuilderMap* builder_map) {
+  Table::Builder* raw_head_builder = GetBuilder(builder_map, Tag::head);
+  FontHeaderTableBuilderPtr header_table_builder;
+  if (raw_head_builder != NULL) {
+      header_table_builder =
+          down_cast<FontHeaderTable::Builder*>(raw_head_builder);
+  }
+
+  Table::Builder* raw_hhea_builder = GetBuilder(builder_map, Tag::hhea);
+  HorizontalHeaderTableBuilderPtr horizontal_header_builder;
+  if (raw_head_builder != NULL) {
+      horizontal_header_builder =
+          down_cast<HorizontalHeaderTable::Builder*>(raw_hhea_builder);
+  }
+
+  Table::Builder* raw_maxp_builder = GetBuilder(builder_map, Tag::maxp);
+  MaximumProfileTableBuilderPtr max_profile_builder;
+  if (raw_maxp_builder != NULL) {
+      max_profile_builder =
+          down_cast<MaximumProfileTable::Builder*>(raw_maxp_builder);
+  }
+
+  Table::Builder* raw_loca_builder = GetBuilder(builder_map, Tag::loca);
+  LocaTableBuilderPtr loca_table_builder;
+  if (raw_loca_builder != NULL) {
+      loca_table_builder = down_cast<LocaTable::Builder*>(raw_loca_builder);
+  }
+
+  Table::Builder* raw_hmtx_builder = GetBuilder(builder_map, Tag::hmtx);
+  HorizontalMetricsTableBuilderPtr horizontal_metrics_builder;
+  if (raw_hmtx_builder != NULL) {
+      horizontal_metrics_builder =
+          down_cast<HorizontalMetricsTable::Builder*>(raw_hmtx_builder);
+  }
+
+#if defined (SFNTLY_EXPERIMENTAL)
+  Table::Builder* raw_hdmx_builder = GetBuilder(builder_map, Tag::hdmx);
+  HorizontalDeviceMetricsTableBuilderPtr hdmx_table_builder;
+  if (raw_hdmx_builder != NULL) {
+      hdmx_table_builder =
+          down_cast<HorizontalDeviceMetricsTable::Builder*>(raw_hdmx_builder);
+  }
+#endif
+
+  // set the inter table data required to build certain tables
+  if (horizontal_metrics_builder != NULL) {
+    if (max_profile_builder != NULL) {
+      horizontal_metrics_builder->SetNumGlyphs(
+          max_profile_builder->NumGlyphs());
+    }
+    if (horizontal_header_builder != NULL) {
+      horizontal_metrics_builder->SetNumberOfHMetrics(
+          horizontal_header_builder->NumberOfHMetrics());
+    }
+  }
+
+  if (loca_table_builder != NULL) {
+    if (max_profile_builder != NULL) {
+      loca_table_builder->SetNumGlyphs(max_profile_builder->NumGlyphs());
+    }
+    if (header_table_builder != NULL) {
+      loca_table_builder->set_format_version(
+          header_table_builder->IndexToLocFormat());
+    }
+  }
+
+#if defined (SFNTLY_EXPERIMENTAL)
+  // Note: In C++, hdmx_table_builder can be NULL in a subsetter.
+  if (max_profile_builder != NULL && hdmx_table_builder != NULL) {
+    hdmx_table_builder->SetNumGlyphs(max_profile_builder->NumGlyphs());
+  }
+#endif
+}
+
+void Font::Builder::ReadHeader(FontInputStream* is,
+                               HeaderOffsetSortedSet* records) {
+  assert(records);
+  sfnt_version_ = is->ReadFixed();
+  num_tables_ = is->ReadUShort();
+  search_range_ = is->ReadUShort();
+  entry_selector_ = is->ReadUShort();
+  range_shift_ = is->ReadUShort();
+
+  for (int32_t table_number = 0; table_number < num_tables_; ++table_number) {
+    // Need to use temporary vars here.  C++ evaluates function parameters from
+    // right to left and thus breaks the order of input stream.
+    int32_t tag = is->ReadULongAsInt();
+    int64_t checksum = is->ReadULong();
+    int32_t offset = is->ReadULongAsInt();
+    int32_t length = is->ReadULongAsInt();
+    HeaderPtr table = new Header(tag, checksum, offset, length);
+    records->insert(table);
+  }
+}
+
+void Font::Builder::ReadHeader(ReadableFontData* fd,
+                               int32_t offset,
+                               HeaderOffsetSortedSet* records) {
+  assert(records);
+  sfnt_version_ = fd->ReadFixed(offset + Offset::kSfntVersion);
+  num_tables_ = fd->ReadUShort(offset + Offset::kNumTables);
+  search_range_ = fd->ReadUShort(offset + Offset::kSearchRange);
+  entry_selector_ = fd->ReadUShort(offset + Offset::kEntrySelector);
+  range_shift_ = fd->ReadUShort(offset + Offset::kRangeShift);
+
+  int32_t table_offset = offset + Offset::kTableRecordBegin;
+  for (int32_t table_number = 0;
+       table_number < num_tables_;
+       table_number++, table_offset += Offset::kTableRecordSize) {
+    int32_t tag = fd->ReadULongAsInt(table_offset + Offset::kTableTag);
+    int64_t checksum = fd->ReadULong(table_offset + Offset::kTableCheckSum);
+    int32_t offset = fd->ReadULongAsInt(table_offset + Offset::kTableOffset);
+    int32_t length = fd->ReadULongAsInt(table_offset + Offset::kTableLength);
+    HeaderPtr table = new Header(tag, checksum, offset, length);
+    records->insert(table);
+  }
+}
+
+void Font::Builder::LoadTableData(HeaderOffsetSortedSet* headers,
+                                  FontInputStream* is,
+                                  DataBlockMap* table_data) {
+  assert(table_data);
+  for (HeaderOffsetSortedSet::iterator table_header = headers->begin(),
+                                       table_end = headers->end();
+                                       table_header != table_end;
+                                       ++table_header) {
+    is->Skip((*table_header)->offset() - is->position());
+    FontInputStream table_is(is, (*table_header)->length());
+    WritableFontDataPtr data;
+    data.Attach(
+        WritableFontData::CreateWritableFontData((*table_header)->length()));
+    data->CopyFrom(&table_is, (*table_header)->length());
+    table_data->insert(DataBlockEntry(*table_header, data));
+  }
+}
+
+void Font::Builder::LoadTableData(HeaderOffsetSortedSet* headers,
+                                  WritableFontData* fd,
+                                  DataBlockMap* table_data) {
+  for (HeaderOffsetSortedSet::iterator table_header = headers->begin(),
+                                       table_end = headers->end();
+                                       table_header != table_end;
+                                       ++table_header) {
+    FontDataPtr sliced_data;
+    sliced_data.Attach(
+        fd->Slice((*table_header)->offset(), (*table_header)->length()));
+    WritableFontDataPtr data = down_cast<WritableFontData*>(sliced_data.p_);
+    table_data->insert(DataBlockEntry(*table_header, data));
+  }
+}
+
+}  // namespace sfntly
diff --git a/sfntly/font.h b/sfntly/font.h
new file mode 100644
index 0000000..975e8cc
--- /dev/null
+++ b/sfntly/font.h
@@ -0,0 +1,352 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_FONT_H_
+#define SFNTLY_CPP_SRC_SFNTLY_FONT_H_
+
+#include <vector>
+
+#include "sfntly/port/refcount.h"
+#include "sfntly/port/type.h"
+#include "sfntly/port/endian.h"
+#include "sfntly/data/font_input_stream.h"
+#include "sfntly/data/font_output_stream.h"
+#include "sfntly/data/writable_font_data.h"
+#include "sfntly/table/table.h"
+
+namespace sfntly {
+
+// Note: following constants are embedded in Font class in Java.  They are
+//       extracted out for easier reference from other classes.  Offset is the
+//       one that is kept within class.
+// Platform ids. These are used in a number of places within the font whenever
+// the platform needs to be specified.
+struct PlatformId {
+  enum {
+    kUnknown = -1,
+    kUnicode = 0,
+    kMacintosh = 1,
+    kISO = 2,
+    kWindows = 3,
+    kCustom = 4
+  };
+};
+
+// Unicode encoding ids. These are used in a number of places within the font
+// whenever character encodings need to be specified.
+struct UnicodeEncodingId {
+  enum {
+    kUnknown = -1,
+    kUnicode1_0 = 0,
+    kUnicode1_1 = 1,
+    kISO10646 = 2,
+    kUnicode2_0_BMP = 3,
+    kUnicode2_0 = 4,
+    kUnicodeVariationSequences = 5
+  };
+};
+
+// Windows encoding ids. These are used in a number of places within the font
+// whenever character encodings need to be specified.
+struct WindowsEncodingId {
+  enum {
+    kUnknown = 0xffffffff,
+    kSymbol = 0,
+    kUnicodeUCS2 = 1,
+    kShiftJIS = 2,
+    kPRC = 3,
+    kBig5 = 4,
+    kWansung = 5,
+    kJohab = 6,
+    kUnicodeUCS4 = 10
+  };
+};
+
+// Macintosh encoding ids. These are used in a number of places within the
+// font whenever character encodings need to be specified.
+struct MacintoshEncodingId {
+  // Macintosh Platform Encodings
+  enum {
+    kUnknown = -1,
+    kRoman = 0,
+    kJapanese = 1,
+    kChineseTraditional = 2,
+    kKorean = 3,
+    kArabic = 4,
+    kHebrew = 5,
+    kGreek = 6,
+    kRussian = 7,
+    kRSymbol = 8,
+    kDevanagari = 9,
+    kGurmukhi = 10,
+    kGujarati = 11,
+    kOriya = 12,
+    kBengali = 13,
+    kTamil = 14,
+    kTelugu = 15,
+    kKannada = 16,
+    kMalayalam = 17,
+    kSinhalese = 18,
+    kBurmese = 19,
+    kKhmer = 20,
+    kThai = 21,
+    kLaotian = 22,
+    kGeorgian = 23,
+    kArmenian = 24,
+    kChineseSimplified = 25,
+    kTibetan = 26,
+    kMongolian = 27,
+    kGeez = 28,
+    kSlavic = 29,
+    kVietnamese = 30,
+    kSindhi = 31,
+    kUninterpreted = 32
+  };
+};
+
+class FontFactory;
+
+// An sfnt container font object. This object is immutable and thread safe. To
+// construct one use an instance of Font::Builder.
+class Font : public RefCounted<Font> {
+ public:
+  // A builder for a font object. The builder allows the for the creation of
+  // immutable Font objects. The builder is a one use non-thread safe object and
+  // once the Font object has been created it is no longer usable. To create a
+  // further Font object new builder will be required.
+  class Builder : public RefCounted<Builder> {
+   public:
+    virtual ~Builder();
+
+    static CALLER_ATTACH Builder*
+        GetOTFBuilder(FontFactory* factory, InputStream* is);
+    static CALLER_ATTACH Builder*
+        GetOTFBuilder(FontFactory* factory,
+                      WritableFontData* ba,
+                      int32_t offset_to_offset_table);
+    static CALLER_ATTACH Builder* GetOTFBuilder(FontFactory* factory);
+
+    // Get the font factory that created this font builder.
+    FontFactory* GetFontFactory() { return factory_; }
+
+    // Is the font ready to build?
+    bool ReadyToBuild();
+
+    // Build the Font. After this call this builder will no longer be usable.
+    CALLER_ATTACH Font* Build();
+
+    // Set a unique fingerprint for the font object.
+    void SetDigest(ByteVector* digest);
+
+    // Clear all table builders.
+    void ClearTableBuilders();
+
+    // Does this font builder have the specified table builder.
+    bool HasTableBuilder(int32_t tag);
+
+    // Get the table builder for the given tag. If there is no builder for that
+    // tag then return a null.
+    Table::Builder* GetTableBuilder(int32_t tag);
+
+    // Creates a new table builder for the table type given by the table id tag.
+    // This new table has been added to the font and will replace any existing
+    // builder for that table.
+    // @return new empty table of the type specified by tag; if tag is not known
+    //         then a generic OpenTypeTable is returned
+    virtual Table::Builder* NewTableBuilder(int32_t tag);
+
+    // Creates a new table builder for the table type given by the table id tag.
+    // It makes a copy of the data provided and uses that copy for the table.
+    // This new table has been added to the font and will replace any existing
+    // builder for that table.
+    virtual Table::Builder* NewTableBuilder(int32_t tag,
+                                            ReadableFontData* src_data);
+
+    // Get a map of the table builders in this font builder accessed by table
+    // tag.
+    virtual TableBuilderMap* table_builders() { return &table_builders_; }
+
+    // Remove the specified table builder from the font builder.
+    // Note: different from Java: we don't return object in removeTableBuilder
+    virtual void RemoveTableBuilder(int32_t tag);
+
+    // Get the number of table builders in the font builder.
+    virtual int32_t number_of_table_builders() {
+      return (int32_t)table_builders_.size();
+    }
+
+   private:
+    explicit Builder(FontFactory* factory);
+    virtual void LoadFont(InputStream* is);
+    virtual void LoadFont(WritableFontData* wfd,
+                          int32_t offset_to_offset_table);
+    int32_t SfntWrapperSize();
+    void BuildAllTableBuilders(DataBlockMap* table_data,
+                               TableBuilderMap* builder_map);
+    CALLER_ATTACH Table::Builder*
+        GetTableBuilder(Header* header, WritableFontData* data);
+    void BuildTablesFromBuilders(Font* font,
+                                 TableBuilderMap* builder_map,
+                                 TableMap* tables);
+    static void InterRelateBuilders(TableBuilderMap* builder_map);
+
+    void ReadHeader(FontInputStream* is,
+                    HeaderOffsetSortedSet* records);
+
+    void ReadHeader(ReadableFontData* fd,
+                    int32_t offset,
+                    HeaderOffsetSortedSet* records);
+
+    void LoadTableData(HeaderOffsetSortedSet* headers,
+                       FontInputStream* is,
+                       DataBlockMap* table_data);
+
+    void LoadTableData(HeaderOffsetSortedSet* headers,
+                       WritableFontData* fd,
+                       DataBlockMap* table_data);
+
+    TableBuilderMap table_builders_;
+    FontFactory* factory_;  // dumb pointer, avoid circular refcounting
+    int32_t sfnt_version_;
+    int32_t num_tables_;
+    int32_t search_range_;
+    int32_t entry_selector_;
+    int32_t range_shift_;
+    DataBlockMap data_blocks_;
+    ByteVector digest_;
+  };
+
+  virtual ~Font();
+
+  // Gets the sfnt version set in the sfnt wrapper of the font.
+  int32_t sfnt_version() { return sfnt_version_; }
+
+  // Gets a copy of the fonts digest that was created when the font was read. If
+  // no digest was set at creation time then the return result will be null.
+  ByteVector* digest() { return &digest_; }
+
+  // Get the checksum for this font.
+  int64_t checksum() { return checksum_; }
+
+  // Get the number of tables in this font.
+  int32_t num_tables() { return (int32_t)tables_.size(); }
+
+  // Whether the font has a particular table.
+  bool HasTable(int32_t tag);
+
+  // UNIMPLEMENTED: public Iterator<? extends Table> iterator
+
+  // Get the table in this font with the specified id.
+  // @param tag the identifier of the table
+  // @return the table specified if it exists; null otherwise
+  // C++ port: rename table() to GetTable()
+  Table* GetTable(int32_t tag);
+
+  // Get a map of the tables in this font accessed by table tag.
+  // @return an unmodifiable view of the tables in this font
+  // Note: renamed tableMap() to GetTableMap()
+  const TableMap* GetTableMap();
+
+  // UNIMPLEMENTED: toString()
+
+  // Serialize the font to the output stream.
+  // @param os the destination for the font serialization
+  // @param tableOrdering the table ordering to apply
+  void Serialize(OutputStream* os, IntegerList* table_ordering);
+
+ private:
+  // Offsets to specific elements in the underlying data. These offsets are
+  // relative to the start of the table or the start of sub-blocks within the
+  // table.
+  struct Offset {
+    enum {
+      // Offsets within the main directory
+      kSfntVersion = 0,
+      kNumTables = 4,
+      kSearchRange = 6,
+      kEntrySelector = 8,
+      kRangeShift = 10,
+      kTableRecordBegin = 12,
+      kSfntHeaderSize = 12,
+
+      // Offsets within a specific table record
+      kTableTag = 0,
+      kTableCheckSum = 4,
+      kTableOffset = 8,
+      kTableLength = 12,
+      kTableRecordSize = 16
+    };
+  };
+
+  // Note: the two constants are moved to tag.h to avoid VC++ bug.
+//  static const int32_t CFF_TABLE_ORDERING[];
+//  static const int32_t TRUE_TYPE_TABLE_ORDERING[];
+
+  // Constructor.
+  // @param sfntVersion the sfnt version
+  // @param digest the computed digest for the font; null if digest was not
+  //        computed
+  // Note: Current C++ port does not support SHA digest validation.
+  Font(int32_t sfnt_version, ByteVector* digest);
+
+  // Build the table headers to be used for serialization. These headers will be
+  // filled out with the data required for serialization. The headers will be
+  // sorted in the order specified and only those specified will have headers
+  // generated.
+  // @param tableOrdering the tables to generate headers for and the order to
+  //        sort them
+  // @return a list of table headers ready for serialization
+  void BuildTableHeadersForSerialization(IntegerList* table_ordering,
+                                         TableHeaderList* table_headers);
+
+  // Searialize the headers.
+  // @param fos the destination stream for the headers
+  // @param tableHeaders the headers to serialize
+  // @throws IOException
+  void SerializeHeader(FontOutputStream* fos, TableHeaderList* table_headers);
+
+  // Serialize the tables.
+  // @param fos the destination stream for the headers
+  // @param tableHeaders the headers for the tables to serialize
+  // @throws IOException
+  void SerializeTables(FontOutputStream* fos, TableHeaderList* table_headers);
+
+  // Generate the full table ordering to used for serialization. The full
+  // ordering uses the partial ordering as a seed and then adds all remaining
+  // tables in the font in an undefined order.
+  // @param defaultTableOrdering the partial ordering to be used as a seed for
+  //        the full ordering
+  // @param (out) table_ordering the full ordering for serialization
+  void GenerateTableOrdering(IntegerList* default_table_ordering,
+                             IntegerList* table_ordering);
+
+  // Get the default table ordering based on the type of the font.
+  // @param (out) default_table_ordering the default table ordering
+  void DefaultTableOrdering(IntegerList* default_table_ordering);
+
+  int32_t sfnt_version_;
+  ByteVector digest_;
+  int64_t checksum_;
+  TableMap tables_;
+};
+typedef Ptr<Font> FontPtr;
+typedef std::vector<FontPtr> FontArray;
+typedef Ptr<Font::Builder> FontBuilderPtr;
+typedef std::vector<FontBuilderPtr> FontBuilderArray;
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_FONT_H_
diff --git a/sfntly/font_factory.cc b/sfntly/font_factory.cc
new file mode 100644
index 0000000..c162a77
--- /dev/null
+++ b/sfntly/font_factory.cc
@@ -0,0 +1,214 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/font_factory.h"
+
+#include <string.h>
+
+#include "sfntly/tag.h"
+
+namespace sfntly {
+
+FontFactory::~FontFactory() {
+}
+
+CALLER_ATTACH FontFactory* FontFactory::GetInstance() {
+  FontFactoryPtr instance = new FontFactory();
+  return instance.Detach();
+}
+
+void FontFactory::FingerprintFont(bool fingerprint) {
+  fingerprint_ = fingerprint;
+}
+
+bool FontFactory::FingerprintFont() {
+  return fingerprint_;
+}
+
+void FontFactory::LoadFonts(InputStream* is, FontArray* output) {
+  assert(output);
+  PushbackInputStream* pbis = down_cast<PushbackInputStream*>(is);
+  if (IsCollection(pbis)) {
+    LoadCollection(pbis, output);
+    return;
+  }
+  FontPtr font;
+  font.Attach(LoadSingleOTF(pbis));
+  if (font) {
+    output->push_back(font);
+  }
+}
+
+void FontFactory::LoadFonts(ByteVector* b, FontArray* output) {
+  WritableFontDataPtr wfd;
+  wfd.Attach(WritableFontData::CreateWritableFontData(b));
+  if (IsCollection(wfd)) {
+    LoadCollection(wfd, output);
+    return;
+  }
+  FontPtr font;
+  font.Attach(LoadSingleOTF(wfd));
+  if (font) {
+    output->push_back(font);
+  }
+}
+
+void FontFactory::LoadFontsForBuilding(InputStream* is,
+                                       FontBuilderArray* output) {
+  PushbackInputStream* pbis = down_cast<PushbackInputStream*>(is);
+  if (IsCollection(pbis)) {
+    LoadCollectionForBuilding(pbis, output);
+    return;
+  }
+  FontBuilderPtr builder;
+  builder.Attach(LoadSingleOTFForBuilding(pbis));
+  if (builder) {
+    output->push_back(builder);
+  }
+}
+
+void FontFactory::LoadFontsForBuilding(ByteVector* b,
+                                       FontBuilderArray* output) {
+  WritableFontDataPtr wfd;
+  wfd.Attach(WritableFontData::CreateWritableFontData(b));
+  if (IsCollection(wfd)) {
+    LoadCollectionForBuilding(wfd, output);
+    return;
+  }
+  FontBuilderPtr builder;
+  builder.Attach(LoadSingleOTFForBuilding(wfd, 0));
+  if (builder) {
+    output->push_back(builder);
+  }
+}
+
+void FontFactory::SerializeFont(Font* font, OutputStream* os) {
+  font->Serialize(os, &table_ordering_);
+}
+
+void FontFactory::SetSerializationTableOrdering(
+    const IntegerList& table_ordering) {
+  table_ordering_ = table_ordering;
+}
+
+CALLER_ATTACH Font::Builder* FontFactory::NewFontBuilder() {
+  return Font::Builder::GetOTFBuilder(this);
+}
+
+CALLER_ATTACH Font* FontFactory::LoadSingleOTF(InputStream* is) {
+  FontBuilderPtr builder;
+  builder.Attach(LoadSingleOTFForBuilding(is));
+  return builder->Build();
+}
+
+CALLER_ATTACH Font* FontFactory::LoadSingleOTF(WritableFontData* wfd) {
+  FontBuilderPtr builder;
+  builder.Attach(LoadSingleOTFForBuilding(wfd, 0));
+  return builder->Build();
+}
+
+void FontFactory::LoadCollection(InputStream* is, FontArray* output) {
+  FontBuilderArray ba;
+  LoadCollectionForBuilding(is, &ba);
+  output->reserve(ba.size());
+  for (FontBuilderArray::iterator builder = ba.begin(), builders_end = ba.end();
+                                  builder != builders_end; ++builder) {
+      FontPtr font;
+      font.Attach((*builder)->Build());
+      output->push_back(font);
+  }
+}
+
+void FontFactory::LoadCollection(WritableFontData* wfd, FontArray* output) {
+  FontBuilderArray builders;
+  LoadCollectionForBuilding(wfd, &builders);
+  output->reserve(builders.size());
+  for (FontBuilderArray::iterator builder = builders.begin(),
+                                  builders_end = builders.end();
+                                  builder != builders_end; ++builder) {
+    FontPtr font;
+    font.Attach((*builder)->Build());
+    output->push_back(font);
+  }
+}
+
+CALLER_ATTACH
+Font::Builder* FontFactory::LoadSingleOTFForBuilding(InputStream* is) {
+  // UNIMPLEMENTED: SHA-1 hash checking via Java DigestStream
+  Font::Builder* builder = Font::Builder::GetOTFBuilder(this, is);
+  // UNIMPLEMENTED: setDigest
+  return builder;
+}
+
+CALLER_ATTACH Font::Builder*
+    FontFactory::LoadSingleOTFForBuilding(WritableFontData* wfd,
+                                          int32_t offset_to_offset_table) {
+  // UNIMPLEMENTED: SHA-1 hash checking via Java DigestStream
+  Font::Builder* builder =
+      Font::Builder::GetOTFBuilder(this, wfd, offset_to_offset_table);
+  // UNIMPLEMENTED: setDigest
+  return builder;
+}
+
+void FontFactory::LoadCollectionForBuilding(InputStream* is,
+                                            FontBuilderArray* builders) {
+  assert(is);
+  assert(builders);
+  WritableFontDataPtr wfd;
+  wfd.Attach(WritableFontData::CreateWritableFontData(is->Available()));
+  wfd->CopyFrom(is);
+  LoadCollectionForBuilding(wfd, builders);
+}
+
+void FontFactory::LoadCollectionForBuilding(WritableFontData* wfd,
+                                            FontBuilderArray* builders) {
+  int32_t ttc_tag = wfd->ReadULongAsInt(Offset::kTTCTag);
+  UNREFERENCED_PARAMETER(ttc_tag);
+  int32_t version = wfd->ReadFixed(Offset::kVersion);
+  UNREFERENCED_PARAMETER(version);
+  int32_t num_fonts = wfd->ReadULongAsInt(Offset::kNumFonts);
+
+  builders->reserve(num_fonts);
+  int32_t offset_table_offset = Offset::kOffsetTable;
+  for (int32_t font_number = 0;
+               font_number < num_fonts;
+               font_number++, offset_table_offset += DataSize::kULONG) {
+    int32_t offset = wfd->ReadULongAsInt(offset_table_offset);
+    FontBuilderPtr builder;
+    builder.Attach(LoadSingleOTFForBuilding(wfd, offset));
+    builders->push_back(builder);
+  }
+}
+
+bool FontFactory::IsCollection(PushbackInputStream* pbis) {
+  ByteVector tag(4);
+  pbis->Read(&tag);
+  pbis->Unread(&tag);
+  return Tag::ttcf == GenerateTag(tag[0], tag[1], tag[2], tag[3]);
+}
+
+bool FontFactory::IsCollection(ReadableFontData* rfd) {
+  ByteVector tag(4);
+  rfd->ReadBytes(0, &(tag[0]), 0, tag.size());
+  return Tag::ttcf ==
+         GenerateTag(tag[0], tag[1], tag[2], tag[3]);
+}
+
+FontFactory::FontFactory()
+    : fingerprint_(false) {
+}
+
+}  // namespace sfntly
diff --git a/sfntly/font_factory.h b/sfntly/font_factory.h
new file mode 100644
index 0000000..63deff4
--- /dev/null
+++ b/sfntly/font_factory.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_FONT_FACTORY_H_
+#define SFNTLY_CPP_SRC_SFNTLY_FONT_FACTORY_H_
+
+#include <vector>
+
+#include "sfntly/port/refcount.h"
+#include "sfntly/port/type.h"
+#include "sfntly/font.h"
+
+namespace sfntly {
+
+class FontFactory : public RefCounted<FontFactory> {
+ public:
+  virtual ~FontFactory();
+
+  // Factory method for the construction of a font factory.
+  static CALLER_ATTACH FontFactory* GetInstance();
+
+  // Toggle whether fonts that are loaded are fingerprinted with a SHA-1 hash.
+  // If a font is fingerprinted then a SHA-1 hash is generated at load time and
+  // stored in the font. This is useful for uniquely identifying fonts. By
+  // default this is turned on.
+  // @param fingerprint whether fingerprinting should be turned on or off
+  // TODO(arthurhsu): IMPLEMENT: C++ port currently don't do any SHA-1
+  void FingerprintFont(bool fingerprint);
+  bool FingerprintFont();
+
+  // Load the font(s) from the input stream. The current settings on the factory
+  // are used during the loading process. One or more fonts are returned if the
+  // stream contains valid font data. Some font container formats may have more
+  // than one font and in this case multiple font objects will be returned. If
+  // the data in the stream cannot be parsed or is invalid an array of size zero
+  // will be returned.
+  void LoadFonts(InputStream* is, FontArray* output);
+
+  // ByteArray font loading
+  // Load the font(s) from the byte array. The current settings on the factory
+  // are used during the loading process. One or more fonts are returned if the
+  // stream contains valid font data. Some font container formats may have more
+  // than one font and in this case multiple font objects will be returned. If
+  // the data in the stream cannot be parsed or is invalid an array of size zero
+  // will be returned.
+  void LoadFonts(ByteVector* b, FontArray* output);
+
+  // Load the font(s) from the input stream into font builders. The current
+  // settings on the factory are used during the loading process. One or more
+  // font builders are returned if the stream contains valid font data. Some
+  // font container formats may have more than one font and in this case
+  // multiple font builder objects will be returned. If the data in the stream
+  // cannot be parsed or is invalid an array of size zero will be returned.
+  void LoadFontsForBuilding(InputStream* is, FontBuilderArray* output);
+
+  // Load the font(s) from the byte array into font builders. The current
+  // settings on the factory are used during the loading process. One or more
+  // font builders are returned if the stream contains valid font data. Some
+  // font container formats may have more than one font and in this case
+  // multiple font builder objects will be returned. If the data in the stream
+  // cannot be parsed or is invalid an array of size zero will be returned.
+  void LoadFontsForBuilding(ByteVector* b, FontBuilderArray* output);
+
+  // Font serialization
+  // Serialize the font to the output stream.
+  // NOTE: in this port we attempted not to implement I/O stream because dealing
+  //       with cross-platform I/O stream itself is big enough as a project.
+  //       Byte buffer it is.
+  void SerializeFont(Font* font, OutputStream* os);
+
+  // Set the table ordering to be used in serializing a font. The table ordering
+  // is an ordered list of table ids and tables will be serialized in the order
+  // given. Any tables whose id is not listed in the ordering will be placed in
+  // an unspecified order following those listed.
+  void SetSerializationTableOrdering(const IntegerList& table_ordering);
+
+  // Get an empty font builder for creating a new font from scratch.
+  CALLER_ATTACH Font::Builder* NewFontBuilder();
+
+ private:
+  // Offsets to specific elements in the underlying data. These offsets are
+  // relative to the start of the table or the start of sub-blocks within the
+  // table.
+  struct Offset {
+    enum {
+      // Offsets within the main directory.
+      kTTCTag = 0,
+      kVersion = 4,
+      kNumFonts = 8,
+      kOffsetTable = 12,
+
+      // TTC Version 2.0 extensions.
+      // Offsets from end of OffsetTable.
+      kulDsigTag = 0,
+      kulDsigLength = 4,
+      kulDsigOffset = 8
+    };
+  };
+
+  FontFactory();
+
+  CALLER_ATTACH Font* LoadSingleOTF(InputStream* is);
+  CALLER_ATTACH Font* LoadSingleOTF(WritableFontData* wfd);
+
+  void LoadCollection(InputStream* is, FontArray* output);
+  void LoadCollection(WritableFontData* wfd, FontArray* output);
+
+  CALLER_ATTACH Font::Builder* LoadSingleOTFForBuilding(InputStream* is);
+  CALLER_ATTACH Font::Builder*
+      LoadSingleOTFForBuilding(WritableFontData* wfd,
+                               int32_t offset_to_offset_table);
+
+  void LoadCollectionForBuilding(InputStream* is, FontBuilderArray* builders);
+  void LoadCollectionForBuilding(WritableFontData* ba,
+                                 FontBuilderArray* builders);
+
+  static bool IsCollection(PushbackInputStream* pbis);
+  static bool IsCollection(ReadableFontData* wfd);
+
+  bool fingerprint_;
+  IntegerList table_ordering_;
+};
+typedef Ptr<FontFactory> FontFactoryPtr;
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_FONT_FACTORY_H_
diff --git a/sfntly/math/fixed1616.h b/sfntly/math/fixed1616.h
new file mode 100644
index 0000000..4abbe18
--- /dev/null
+++ b/sfntly/math/fixed1616.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_MATH_FIXED1616_H_
+#define SFNTLY_CPP_SRC_SFNTLY_MATH_FIXED1616_H_
+
+#include "sfntly/port/type.h"
+
+namespace sfntly {
+
+class Fixed1616 {
+ public:
+  static inline int32_t Integral(int32_t fixed) {
+    return (fixed >> 16);
+  }
+
+  static inline int32_t Fractional(int32_t fixed) {
+    return (fixed & 0xffff);
+  }
+
+  static inline int32_t Fixed(int32_t integral, int32_t fractional) {
+    return ((integral & 0xffff) << 16) | (fractional & 0xffff);
+  }
+};
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_MATH_FIXED1616_H_
diff --git a/sfntly/math/font_math.h b/sfntly/math/font_math.h
new file mode 100644
index 0000000..f1cd2d2
--- /dev/null
+++ b/sfntly/math/font_math.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_MATH_FONT_MATH_H_
+#define SFNTLY_CPP_SRC_SFNTLY_MATH_FONT_MATH_H_
+
+#include "sfntly/port/type.h"
+
+namespace sfntly {
+
+class FontMath {
+ public:
+  static int32_t Log2(int32_t a) {
+    int r = 0;  // r will be lg(a)
+    while (a != 0) {
+      a >>= 1;
+      r++;
+    }
+    return r - 1;
+  }
+
+  // Calculates the amount of padding needed. The values provided need to be in
+  // the same units. So, if the size is given as the number of bytes then the
+  // alignment size must also be specified as byte size to align to.
+  // @param size the size of the data that may need padding
+  // @param alignmentSize the number of units to align to
+  // @return the number of units needing to be added for alignment
+  static int32_t PaddingRequired(int32_t size, int32_t alignment_size) {
+    int32_t padding = alignment_size - (size % alignment_size);
+    return padding == alignment_size ? 0 : padding;
+  }
+};
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_MATH_FONT_MATH_H_
diff --git a/sfntly/port/atomic.h b/sfntly/port/atomic.h
new file mode 100644
index 0000000..b381a52
--- /dev/null
+++ b/sfntly/port/atomic.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_PORT_ATOMIC_H_
+#define SFNTLY_CPP_SRC_SFNTLY_PORT_ATOMIC_H_
+
+#if defined (WIN32)
+
+#include <windows.h>
+
+static inline size_t AtomicIncrement(size_t* address) {
+#if defined (_WIN64)
+  return InterlockedIncrement64(reinterpret_cast<LONGLONG*>(address));
+#else
+  return InterlockedIncrement(reinterpret_cast<LONG*>(address));
+#endif
+}
+
+static inline size_t AtomicDecrement(size_t* address) {
+#if defined (_WIN64)
+  return InterlockedDecrement64(reinterpret_cast<LONGLONG*>(address));
+#else
+  return InterlockedDecrement(reinterpret_cast<LONG*>(address));
+#endif
+}
+
+#elif defined (__APPLE__)
+
+#include <libkern/OSAtomic.h>
+
+static inline size_t AtomicIncrement(size_t* address) {
+  return OSAtomicIncrement32Barrier(reinterpret_cast<int32_t*>(address));
+}
+
+static inline size_t AtomicDecrement(size_t* address) {
+  return OSAtomicDecrement32Barrier(reinterpret_cast<int32_t*>(address));
+}
+
+// Originally we check __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4, however, there are
+// issues that clang not carring over this definition.  Therefore we boldly
+// assume it's gcc or gcc-compatible here.  Compilation shall still fail since
+// the intrinsics used are GCC-specific.
+
+#else
+
+#include <stddef.h>
+
+static inline size_t AtomicIncrement(size_t* address) {
+  return __sync_add_and_fetch(address, 1);
+}
+
+static inline size_t AtomicDecrement(size_t* address) {
+  return __sync_sub_and_fetch(address, 1);
+}
+
+#endif  // WIN32
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_PORT_ATOMIC_H_
diff --git a/sfntly/port/config.h b/sfntly/port/config.h
new file mode 100644
index 0000000..0fcdffe
--- /dev/null
+++ b/sfntly/port/config.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_PORT_CONFIG_H_
+#define SFNTLY_CPP_SRC_SFNTLY_PORT_CONFIG_H_
+
+#if !defined(SFNTLY_BIG_ENDIAN) && !defined(SFNTLY_LITTLE_ENDIAN)
+  #if defined (__ppc__) || defined (__ppc64__)
+    #define SFNTLY_BIG_ENDIAN
+  #else
+    #define SFNTLY_LITTLE_ENDIAN
+  #endif
+#endif
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_PORT_CONFIG_H_
diff --git a/sfntly/port/endian.h b/sfntly/port/endian.h
new file mode 100644
index 0000000..db58f0a
--- /dev/null
+++ b/sfntly/port/endian.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_PORT_ENDIAN_H_
+#define SFNTLY_CPP_SRC_SFNTLY_PORT_ENDIAN_H_
+
+#include "sfntly/port/config.h"
+#include "sfntly/port/type.h"
+
+namespace sfntly {
+
+static inline uint16_t EndianSwap16(uint16_t value) {
+  return (uint16_t)((value >> 8) | (value << 8));
+}
+
+static inline int32_t EndianSwap32(int32_t value) {
+  return (((value & 0x000000ff) << 24) |
+          ((value & 0x0000ff00) <<  8) |
+          ((value & 0x00ff0000) >>  8) |
+          ((value & 0xff000000) >> 24));
+}
+
+static inline uint64_t EndianSwap64(uint64_t value) {
+  return (((value & 0x00000000000000ffLL) << 56) |
+          ((value & 0x000000000000ff00LL) << 40) |
+          ((value & 0x0000000000ff0000LL) << 24) |
+          ((value & 0x00000000ff000000LL) << 8)  |
+          ((value & 0x000000ff00000000LL) >> 8)  |
+          ((value & 0x0000ff0000000000LL) >> 24) |
+          ((value & 0x00ff000000000000LL) >> 40) |
+          ((value & 0xff00000000000000LL) >> 56));
+}
+
+#ifdef SFNTLY_LITTLE_ENDIAN
+  #define ToBE16(n) EndianSwap16(n)
+  #define ToBE32(n) EndianSwap32(n)
+  #define ToBE64(n) EndianSwap64(n)
+  #define ToLE16(n) (n)
+  #define ToLE32(n) (n)
+  #define ToLE64(n) (n)
+  #define FromBE16(n) EndianSwap16(n)
+  #define FromBE32(n) EndianSwap32(n)
+  #define FromBE64(n) EndianSwap64(n)
+  #define FromLE16(n) (n)
+  #define FromLE32(n) (n)
+  #define FromLE64(n) (n)
+#else  // SFNTLY_BIG_ENDIAN
+  #define ToBE16(n) (n)
+  #define ToBE32(n) (n)
+  #define ToBE64(n) (n)
+  #define ToLE16(n) EndianSwap16(n)
+  #define ToLE32(n) EndianSwap32(n)
+  #define ToLE64(n) EndianSwap64(n)
+  #define FromBE16(n) (n)
+  #define FromBE32(n) (n)
+  #define FromBE64(n) (n)
+  #define FromLE16(n) EndianSwap16(n)
+  #define FromLE32(n) EndianSwap32(n)
+  #define FromLE64(n) EndianSwap64(n)
+#endif
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_PORT_ENDIAN_H_
diff --git a/sfntly/port/exception_type.h b/sfntly/port/exception_type.h
new file mode 100644
index 0000000..b96efcb
--- /dev/null
+++ b/sfntly/port/exception_type.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+// Exceptions used in sfntly
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_PORT_EXCEPTION_TYPE_H_
+#define SFNTLY_CPP_SRC_SFNTLY_PORT_EXCEPTION_TYPE_H_
+
+#if !defined (SFNTLY_NO_EXCEPTION)
+
+#include <exception>
+#include <string>
+#include <sstream>
+
+namespace sfntly {
+
+class Exception : public std::exception {
+ public:
+  Exception() : what_("Unknown exception") {}
+  explicit Exception(const char* message) throw() { SetMessage(message); }
+  virtual ~Exception() throw() {}
+  virtual const char* what() const throw() { return what_.c_str(); }
+
+ protected:
+  void SetMessage(const char* message) throw() {
+    try {
+      what_ = message;
+    } catch (...) {}
+  }
+
+ private:
+  std::string what_;
+};
+
+class IndexOutOfBoundException : public Exception {
+ public:
+  IndexOutOfBoundException() throw() : Exception("Index out of bound") {}
+  explicit IndexOutOfBoundException(const char* message) throw()
+      : Exception(message) {}
+  IndexOutOfBoundException(const char* message, int32_t index) throw() {
+    try {
+      std::ostringstream msg;
+      msg << message;
+      msg << ":";
+      msg << index;
+      SetMessage(msg.str().c_str());
+    } catch (...) {}
+  }
+  virtual ~IndexOutOfBoundException() throw() {}
+};
+
+class IOException : public Exception {
+ public:
+  IOException() throw() : Exception("I/O exception") {}
+  explicit IOException(const char* message) throw() : Exception(message) {}
+  virtual ~IOException() throw() {}
+};
+
+class ArithmeticException : public Exception {
+ public:
+  ArithmeticException() throw() : Exception("Arithmetic exception") {}
+  explicit ArithmeticException(const char* message) throw()
+      : Exception(message) {}
+  virtual ~ArithmeticException() throw() {}
+};
+
+class UnsupportedOperationException : public Exception {
+ public:
+  UnsupportedOperationException() throw() :
+      Exception("Operation not supported") {}
+  explicit UnsupportedOperationException(const char* message) throw()
+      : Exception(message) {}
+  virtual ~UnsupportedOperationException() throw() {}
+};
+
+class RuntimeException : public Exception {
+ public:
+  RuntimeException() throw() : Exception("Runtime exception") {}
+  explicit RuntimeException(const char* message) throw()
+      : Exception(message) {}
+  virtual ~RuntimeException() throw() {}
+};
+
+class NoSuchElementException : public Exception {
+ public:
+  NoSuchElementException() throw() : Exception("No such element") {}
+  explicit NoSuchElementException(const char* message) throw()
+      : Exception(message) {}
+  virtual ~NoSuchElementException() throw() {}
+};
+
+class IllegalArgumentException : public Exception {
+ public:
+  IllegalArgumentException() throw() : Exception("Illegal argument") {}
+  explicit IllegalArgumentException(const char* message) throw()
+      : Exception(message) {}
+  virtual ~IllegalArgumentException() throw() {}
+};
+
+class IllegalStateException : public Exception {
+ public:
+  IllegalStateException() throw() : Exception("Illegal state") {}
+  explicit IllegalStateException(const char* message) throw()
+      : Exception(message) {}
+  virtual ~IllegalStateException() throw() {}
+};
+
+}  // namespace sfntly
+
+#endif  // #if !defined (SFNTLY_NO_EXCEPTION)
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_PORT_EXCEPTION_TYPE_H_
diff --git a/sfntly/port/file_input_stream.cc b/sfntly/port/file_input_stream.cc
new file mode 100644
index 0000000..dfe9a7b
--- /dev/null
+++ b/sfntly/port/file_input_stream.cc
@@ -0,0 +1,171 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#if defined (WIN32)
+#include <windows.h>
+#endif
+
+#include <algorithm>
+
+#include "sfntly/port/file_input_stream.h"
+#include "sfntly/port/exception_type.h"
+
+namespace sfntly {
+
+FileInputStream::FileInputStream()
+    : file_(NULL),
+      position_(0),
+      length_(0) {
+}
+
+FileInputStream::~FileInputStream() {
+  Close();
+}
+
+int32_t FileInputStream::Available() {
+  return length_ - position_;
+}
+
+void FileInputStream::Close() {
+  if (file_) {
+    fclose(file_);
+    length_ = 0;
+    position_ = 0;
+    file_ = NULL;
+  }
+}
+
+void FileInputStream::Mark(int32_t readlimit) {
+  // NOP
+  UNREFERENCED_PARAMETER(readlimit);
+}
+
+bool FileInputStream::MarkSupported() {
+  return false;
+}
+
+int32_t FileInputStream::Read() {
+  if (!file_) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IOException("no opened file");
+#endif
+    return 0;
+  }
+  if (feof(file_)) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IOException("eof reached");
+#endif
+    return 0;
+  }
+  byte_t value;
+  size_t length = fread(&value, 1, 1, file_);
+  position_ += length;
+  return value;
+}
+
+int32_t FileInputStream::Read(ByteVector* b) {
+  return Read(b, 0, b->size());
+}
+
+int32_t FileInputStream::Read(ByteVector* b, int32_t offset, int32_t length) {
+  assert(b);
+  if (!file_) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IOException("no opened file");
+#endif
+    return 0;
+  }
+  if (feof(file_)) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IOException("eof reached");
+#endif
+    return 0;
+  }
+  size_t read_count = std::min<size_t>(length_ - position_, length);
+  if (b->size() < (size_t)(offset + read_count)) {
+    b->resize((size_t)(offset + read_count));
+  }
+  int32_t actual_read = fread(&((*b)[offset]), 1, read_count, file_);
+  position_ += actual_read;
+  return actual_read;
+}
+
+void FileInputStream::Reset() {
+  // NOP
+}
+
+int64_t FileInputStream::Skip(int64_t n) {
+  if (!file_) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IOException("no opened file");
+#endif
+    return 0;
+  }
+  int64_t skip_count = 0;
+  if (n < 0) {  // move backwards
+    skip_count = std::max<int64_t>(0 - (int64_t)position_, n);
+    position_ -= (size_t)(0 - skip_count);
+    fseek(file_, position_, SEEK_SET);
+  } else {
+    skip_count = std::min<size_t>(length_ - position_, (size_t)n);
+    position_ += (size_t)skip_count;
+    fseek(file_, (size_t)skip_count, SEEK_CUR);
+  }
+  return skip_count;
+}
+
+void FileInputStream::Unread(ByteVector* b) {
+  Unread(b, 0, b->size());
+}
+
+void FileInputStream::Unread(ByteVector* b, int32_t offset, int32_t length) {
+  assert(b);
+  assert(b->size() >= size_t(offset + length));
+  if (!file_) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IOException("no opened file");
+#endif
+    return;
+  }
+  size_t unread_count = std::min<size_t>(position_, length);
+  fseek(file_, position_ - unread_count, SEEK_SET);
+  position_ -= unread_count;
+  Read(b, offset, length);
+  fseek(file_, position_ - unread_count, SEEK_SET);
+  position_ -= unread_count;
+}
+
+bool FileInputStream::Open(const char* file_path) {
+  assert(file_path);
+  if (file_) {
+    Close();
+  }
+#if defined (WIN32)
+  fopen_s(&file_, file_path, "rb");
+#else
+  file_ = fopen(file_path, "rb");
+#endif
+  if (file_ == NULL) {
+    return false;
+  }
+
+  fseek(file_, 0, SEEK_END);
+  length_ = ftell(file_);
+  fseek(file_, 0, SEEK_SET);
+  return true;
+}
+
+}  // namespace sfntly
diff --git a/sfntly/port/file_input_stream.h b/sfntly/port/file_input_stream.h
new file mode 100644
index 0000000..cbca25f
--- /dev/null
+++ b/sfntly/port/file_input_stream.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_PORT_FILE_INPUT_STREAM_H_
+#define SFNTLY_CPP_SRC_SFNTLY_PORT_FILE_INPUT_STREAM_H_
+
+#include <stdio.h>
+
+#include "sfntly/port/input_stream.h"
+
+namespace sfntly {
+
+class FileInputStream : public PushbackInputStream {
+ public:
+  FileInputStream();
+  virtual ~FileInputStream();
+
+  // InputStream methods
+  virtual int32_t Available();
+  virtual void Close();
+  virtual void Mark(int32_t readlimit);
+  virtual bool MarkSupported();
+  virtual int32_t Read();
+  virtual int32_t Read(ByteVector* b);
+  virtual int32_t Read(ByteVector* b, int32_t offset, int32_t length);
+  virtual void Reset();
+  virtual int64_t Skip(int64_t n);
+
+  // PushbackInputStream methods
+  virtual void Unread(ByteVector* b);
+  virtual void Unread(ByteVector* b, int32_t offset, int32_t length);
+
+  // Own methods
+  virtual bool Open(const char* file_path);
+
+ private:
+  FILE* file_;
+  size_t position_;
+  size_t length_;
+};
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_PORT_FILE_INPUT_STREAM_H_
diff --git a/sfntly/port/input_stream.h b/sfntly/port/input_stream.h
new file mode 100644
index 0000000..5d24036
--- /dev/null
+++ b/sfntly/port/input_stream.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_PORT_INPUT_STREAM_H_
+#define SFNTLY_CPP_SRC_SFNTLY_PORT_INPUT_STREAM_H_
+
+#include "sfntly/port/type.h"
+
+namespace sfntly {
+
+// C++ equivalent to Java's OutputStream class
+class InputStream {
+ public:
+  // Make gcc -Wnon-virtual-dtor happy.
+  virtual ~InputStream() {}
+
+  virtual int32_t Available() = 0;
+  virtual void Close() = 0;
+  virtual void Mark(int32_t readlimit) = 0;
+  virtual bool MarkSupported() = 0;
+  virtual int32_t Read() = 0;
+  virtual int32_t Read(ByteVector* b) = 0;
+  virtual int32_t Read(ByteVector* b, int32_t offset, int32_t length) = 0;
+  virtual void Reset() = 0;
+  virtual int64_t Skip(int64_t n) = 0;
+};
+
+class PushbackInputStream : public InputStream {
+ public:
+  virtual void Unread(ByteVector* b) = 0;
+  virtual void Unread(ByteVector* b, int32_t offset, int32_t length) = 0;
+};
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_PORT_INPUT_STREAM_H_
diff --git a/sfntly/port/java_iterator.h b/sfntly/port/java_iterator.h
new file mode 100644
index 0000000..0a99bca
--- /dev/null
+++ b/sfntly/port/java_iterator.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_PORT_JAVA_ITERATOR_H_
+#define SFNTLY_CPP_SRC_SFNTLY_PORT_JAVA_ITERATOR_H_
+
+#include "sfntly/port/refcount.h"
+
+// Interface of Java iterator.
+// This is a forward read-only iterator that represents java.util.Iterator<E>
+
+namespace sfntly {
+
+template <typename ReturnType, typename ContainerBase>
+class Iterator : public virtual RefCount {
+ public:
+  virtual ~Iterator() {}
+  virtual ContainerBase* container_base() = 0;
+
+ protected:
+  Iterator() {}
+  NO_COPY_AND_ASSIGN(Iterator);
+};
+
+template <typename ReturnType, typename Container,
+          typename ContainerBase = Container>
+class PODIterator : public Iterator<ReturnType, ContainerBase>,
+                    public RefCounted< PODIterator<ReturnType, Container> > {
+ public:
+  explicit PODIterator(Container* container) : container_(container) {}
+  virtual ~PODIterator() {}
+  virtual ContainerBase* container_base() {
+    return static_cast<ContainerBase*>(container_);
+  }
+
+  virtual bool HasNext() = 0;
+  virtual ReturnType Next() = 0;
+  virtual void Remove() {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    // Default to no support.
+    throw UnsupportedOperationException();
+#endif
+  }
+
+ protected:
+  Container* container() { return container_; }
+
+ private:
+  Container* container_;  // Dumb pointer is used to avoid circular ref-counting
+};
+
+template <typename ReturnType, typename Container,
+          typename ContainerBase = Container>
+class RefIterator : public Iterator<ReturnType, ContainerBase>,
+                    public RefCounted< RefIterator<ReturnType, Container> > {
+ public:
+  explicit RefIterator(Container* container) : container_(container) {}
+  virtual ~RefIterator() {}
+  virtual ContainerBase* container_base() {
+    return static_cast<ContainerBase*>(container_);
+  }
+
+  virtual bool HasNext() = 0;
+  CALLER_ATTACH virtual ReturnType* Next() = 0;
+  virtual void Remove() {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    // Default to no support.
+    throw UnsupportedOperationException();
+#endif
+  }
+
+ protected:
+  Container* container() { return container_; }
+
+ private:
+  Container* container_;  // Dumb pointer is used to avoid circular ref-counting
+};
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_PORT_JAVA_ITERATOR_H_
diff --git a/sfntly/port/lock.cc b/sfntly/port/lock.cc
new file mode 100644
index 0000000..6c0c309
--- /dev/null
+++ b/sfntly/port/lock.cc
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/port/lock.h"
+
+namespace sfntly {
+
+#if defined (WIN32)
+
+Lock::Lock() {
+  // The second parameter is the spin count, for short-held locks it avoid the
+  // contending thread from going to sleep which helps performance greatly.
+  ::InitializeCriticalSectionAndSpinCount(&os_lock_, 2000);
+}
+
+Lock::~Lock() {
+  ::DeleteCriticalSection(&os_lock_);
+}
+
+bool Lock::Try() {
+  if (::TryEnterCriticalSection(&os_lock_) != FALSE) {
+    return true;
+  }
+  return false;
+}
+
+void Lock::Acquire() {
+  ::EnterCriticalSection(&os_lock_);
+}
+
+void Lock::Unlock() {
+  ::LeaveCriticalSection(&os_lock_);
+}
+
+#else  // We assume it's pthread
+
+Lock::Lock() {
+  pthread_mutex_init(&os_lock_, NULL);
+}
+
+Lock::~Lock() {
+  pthread_mutex_destroy(&os_lock_);
+}
+
+bool Lock::Try() {
+  return (pthread_mutex_trylock(&os_lock_) == 0);
+}
+
+void Lock::Acquire() {
+  pthread_mutex_lock(&os_lock_);
+}
+
+void Lock::Unlock() {
+  pthread_mutex_unlock(&os_lock_);
+}
+
+#endif
+
+}  // namespace sfntly
diff --git a/sfntly/port/lock.h b/sfntly/port/lock.h
new file mode 100644
index 0000000..b2e29bf
--- /dev/null
+++ b/sfntly/port/lock.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_PORT_LOCK_H_
+#define SFNTLY_CPP_SRC_SFNTLY_PORT_LOCK_H_
+
+#if defined (WIN32)
+#include <windows.h>
+#else  // Assume pthread.
+#include <pthread.h>
+#include <errno.h>
+#endif
+
+#include "sfntly/port/type.h"
+
+namespace sfntly {
+
+#if defined (WIN32)
+  typedef CRITICAL_SECTION OSLockType;
+#else  // Assume pthread.
+  typedef pthread_mutex_t OSLockType;
+#endif
+
+class Lock {
+ public:
+  Lock();
+  ~Lock();
+
+  // If the lock is not held, take it and return true.  If the lock is already
+  // held by something else, immediately return false.
+  bool Try();
+
+  // Take the lock, blocking until it is available if necessary.
+  void Acquire();
+
+  // Release the lock.  This must only be called by the lock's holder: after
+  // a successful call to Try, or a call to Lock.
+  void Unlock();
+
+ private:
+  OSLockType os_lock_;
+  NO_COPY_AND_ASSIGN(Lock);
+};
+
+// A helper class that acquires the given Lock while the AutoLock is in scope.
+class AutoLock {
+ public:
+  explicit AutoLock(Lock& lock) : lock_(lock) {
+    lock_.Acquire();
+  }
+
+  ~AutoLock() {
+    lock_.Unlock();
+  }
+
+ private:
+  Lock& lock_;
+  NO_COPY_AND_ASSIGN(AutoLock);
+};
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_PORT_LOCK_H_
diff --git a/sfntly/port/memory_input_stream.cc b/sfntly/port/memory_input_stream.cc
new file mode 100755
index 0000000..f6f2b9b
--- /dev/null
+++ b/sfntly/port/memory_input_stream.cc
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#if defined (WIN32)
+#include <windows.h>
+#endif
+
+#include <string.h>
+
+#include <algorithm>
+
+#include "sfntly/port/memory_input_stream.h"
+#include "sfntly/port/exception_type.h"
+
+namespace sfntly {
+
+MemoryInputStream::MemoryInputStream()
+    : buffer_(NULL),
+      position_(0),
+      length_(0) {
+}
+
+MemoryInputStream::~MemoryInputStream() {
+  Close();
+}
+
+int32_t MemoryInputStream::Available() {
+  return length_ - position_;
+}
+
+void MemoryInputStream::Close() {
+}
+
+void MemoryInputStream::Mark(int32_t readlimit) {
+  // NOP
+  UNREFERENCED_PARAMETER(readlimit);
+}
+
+bool MemoryInputStream::MarkSupported() {
+  return false;
+}
+
+int32_t MemoryInputStream::Read() {
+  if (!buffer_) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IOException("no memory attached");
+#endif
+    return 0;
+  }
+  if (position_ >= length_) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IOException("eof reached");
+#endif
+    return 0;
+  }
+  byte_t value = buffer_[position_++];
+  return value;
+}
+
+int32_t MemoryInputStream::Read(ByteVector* b) {
+  return Read(b, 0, b->size());
+}
+
+int32_t MemoryInputStream::Read(ByteVector* b, int32_t offset, int32_t length) {
+  assert(b);
+  if (!buffer_) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IOException("no memory attached");
+#endif
+    return 0;
+  }
+  if (position_ >= length_) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IOException("eof reached");
+#endif
+    return 0;
+  }
+  size_t read_count = std::min<size_t>(length_ - position_, length);
+  if (b->size() < (size_t)(offset + read_count)) {
+    b->resize((size_t)(offset + read_count));
+  }
+  memcpy(&((*b)[offset]), buffer_ + position_, read_count);
+  position_ += read_count;
+  return read_count;
+}
+
+void MemoryInputStream::Reset() {
+  // NOP
+}
+
+int64_t MemoryInputStream::Skip(int64_t n) {
+  if (!buffer_) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IOException("no memory attached");
+#endif
+    return 0;
+  }
+  int64_t skip_count = 0;
+  if (n < 0) {  // move backwards
+    skip_count = std::max<int64_t>(0 - (int64_t)position_, n);
+    position_ -= (size_t)(0 - skip_count);
+  } else {
+    skip_count = std::min<size_t>(length_ - position_, (size_t)n);
+    position_ += (size_t)skip_count;
+  }
+  return skip_count;
+}
+
+void MemoryInputStream::Unread(ByteVector* b) {
+  Unread(b, 0, b->size());
+}
+
+void MemoryInputStream::Unread(ByteVector* b, int32_t offset, int32_t length) {
+  assert(b);
+  assert(b->size() >= size_t(offset + length));
+  if (!buffer_) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IOException("no memory attached");
+#endif
+    return;
+  }
+  size_t unread_count = std::min<size_t>(position_, length);
+  position_ -= unread_count;
+  Read(b, offset, length);
+  position_ -= unread_count;
+}
+
+bool MemoryInputStream::Attach(const byte_t* buffer, size_t length) {
+  assert(buffer);
+  assert(length);
+  buffer_ = buffer;
+  length_ = length;
+  return true;
+}
+
+}  // namespace sfntly
diff --git a/sfntly/port/memory_input_stream.h b/sfntly/port/memory_input_stream.h
new file mode 100755
index 0000000..bc861c3
--- /dev/null
+++ b/sfntly/port/memory_input_stream.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_PORT_MEMORY_INPUT_STREAM_H_
+#define SFNTLY_CPP_SRC_SFNTLY_PORT_MEMORY_INPUT_STREAM_H_
+
+#include <stdio.h>
+
+#include "sfntly/port/input_stream.h"
+
+namespace sfntly {
+
+class MemoryInputStream : public PushbackInputStream {
+ public:
+  MemoryInputStream();
+  virtual ~MemoryInputStream();
+
+  // InputStream methods
+  virtual int32_t Available();
+  virtual void Close();
+  virtual void Mark(int32_t readlimit);
+  virtual bool MarkSupported();
+  virtual int32_t Read();
+  virtual int32_t Read(ByteVector* b);
+  virtual int32_t Read(ByteVector* b, int32_t offset, int32_t length);
+  virtual void Reset();
+  virtual int64_t Skip(int64_t n);
+
+  // PushbackInputStream methods
+  virtual void Unread(ByteVector* b);
+  virtual void Unread(ByteVector* b, int32_t offset, int32_t length);
+
+  // Own methods
+  virtual bool Attach(const byte_t* buffer, size_t length);
+
+ private:
+  const byte_t* buffer_;
+  size_t position_;
+  size_t length_;
+};
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_PORT_MEMORY_INPUT_STREAM_H_
diff --git a/sfntly/port/memory_output_stream.cc b/sfntly/port/memory_output_stream.cc
new file mode 100644
index 0000000..f2ff2e3
--- /dev/null
+++ b/sfntly/port/memory_output_stream.cc
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/port/memory_output_stream.h"
+
+namespace sfntly {
+
+MemoryOutputStream::MemoryOutputStream() {
+}
+
+MemoryOutputStream::~MemoryOutputStream() {
+}
+
+void MemoryOutputStream::Write(ByteVector* buffer) {
+  store_.insert(store_.end(), buffer->begin(), buffer->end());
+}
+
+void MemoryOutputStream::Write(ByteVector* buffer,
+                               int32_t offset,
+                               int32_t length) {
+  assert(buffer);
+  if (offset >= 0 && length > 0) {
+    store_.insert(store_.end(),
+                  buffer->begin() + offset,
+                  buffer->begin() + offset + length);
+  } else {
+#if !defined(SFNTLY_NO_EXCEPTION)
+    throw IndexOutOfBoundException();
+#endif
+  }
+}
+
+void MemoryOutputStream::Write(byte_t* buffer, int32_t offset, int32_t length) {
+  assert(buffer);
+  if (offset >= 0 && length > 0) {
+    store_.insert(store_.end(), buffer + offset, buffer + offset + length);
+  } else {
+#if !defined(SFNTLY_NO_EXCEPTION)
+    throw IndexOutOfBoundException();
+#endif
+  }
+}
+
+void MemoryOutputStream::Write(byte_t b) {
+  store_.push_back(b);
+}
+
+byte_t* MemoryOutputStream::Get() {
+  if (store_.empty()) {
+    return NULL;
+  }
+  return &(store_[0]);
+}
+
+size_t MemoryOutputStream::Size() {
+  return store_.size();
+}
+
+}  // namespace sfntly
diff --git a/sfntly/port/memory_output_stream.h b/sfntly/port/memory_output_stream.h
new file mode 100644
index 0000000..d1eda7f
--- /dev/null
+++ b/sfntly/port/memory_output_stream.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_PORT_MEMORY_OUTPUT_STREAM_H_
+#define SFNTLY_CPP_SRC_SFNTLY_PORT_MEMORY_OUTPUT_STREAM_H_
+
+#include <cstddef>
+#include <vector>
+
+#include "sfntly/port/type.h"
+#include "sfntly/port/output_stream.h"
+
+namespace sfntly {
+
+// OutputStream backed by STL vector
+
+class MemoryOutputStream : public OutputStream {
+ public:
+  MemoryOutputStream();
+  virtual ~MemoryOutputStream();
+
+  virtual void Close() {}  // no-op
+  virtual void Flush() {}  // no-op
+  virtual void Write(ByteVector* buffer);
+  virtual void Write(ByteVector* buffer, int32_t offset, int32_t length);
+  virtual void Write(byte_t* buffer, int32_t offset, int32_t length);
+  virtual void Write(byte_t b);
+
+  byte_t* Get();
+  size_t Size();
+
+ private:
+  std::vector<byte_t> store_;
+};
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_PORT_MEMORY_OUTPUT_STREAM_H_
diff --git a/sfntly/port/output_stream.h b/sfntly/port/output_stream.h
new file mode 100644
index 0000000..64a6024
--- /dev/null
+++ b/sfntly/port/output_stream.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_PORT_OUTPUT_STREAM_H_
+#define SFNTLY_CPP_SRC_SFNTLY_PORT_OUTPUT_STREAM_H_
+
+#include "sfntly/port/type.h"
+
+namespace sfntly {
+
+// C++ equivalent to Java's OutputStream class
+class OutputStream {
+ public:
+  // Make gcc -Wnon-virtual-dtor happy.
+  virtual ~OutputStream() {}
+
+  virtual void Close() = 0;
+  virtual void Flush() = 0;
+  virtual void Write(ByteVector* buffer) = 0;
+  virtual void Write(byte_t b) = 0;
+
+  // Note: C++ port offered both versions of Write() here.  The first one is
+  //       better because it does check bounds.  The second one is there for
+  //       performance concerns.
+  virtual void Write(ByteVector* buffer, int32_t offset, int32_t length) = 0;
+
+  // Note: Caller is responsible for the boundary of buffer.
+  virtual void Write(byte_t* buffer, int32_t offset, int32_t length) = 0;
+};
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_PORT_OUTPUT_STREAM_H_
diff --git a/sfntly/port/refcount.h b/sfntly/port/refcount.h
new file mode 100644
index 0000000..eed5162
--- /dev/null
+++ b/sfntly/port/refcount.h
@@ -0,0 +1,277 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+// Object reference count and smart pointer implementation.
+
+// Smart pointer usage in sfntly:
+//
+// sfntly carries a smart pointer implementation like COM.  Ref-countable object
+// type inherits from RefCounted<>, which have AddRef and Release just like
+// IUnknown (but no QueryInterface).  Use a Ptr<> based smart pointer to hold
+// the object so that the object ref count is handled correctly.
+//
+// class Foo : public RefCounted<Foo> {
+//  public:
+//   static Foo* CreateInstance() {
+//     Ptr<Foo> obj = new Foo();  // ref count = 1
+//     return obj.Detach();
+//   }
+// };
+// typedef Ptr<Foo> FooPtr;  // common short-hand notation
+// FooPtr obj;
+// obj.Attach(Foo::CreatedInstance());  // ref count = 1
+// {
+//   FooPtr obj2 = obj;  // ref count = 2
+// }  // ref count = 1, obj2 out of scope
+// obj.Release();  // ref count = 0, object destroyed
+
+// Notes on usage:
+// 1. Virtual inherit from RefCount interface in base class if smart pointers
+//    are going to be defined.
+// 2. All RefCounted objects must be instantiated on the heap.  Allocating the
+//    object on stack will cause crash.
+// 3. Be careful when you have complex inheritance.  For example,
+//    class A : public RefCounted<A>;
+//    class B : public A, public RefCounted<B>;
+//    In this case the smart pointer is pretty dumb and don't count on it to
+//    nicely destroy your objects as designed. Try refactor your code like
+//    class I;  // the common interface and implementations
+//    class A : public I, public RefCounted<A>;  // A specific implementation
+//    class B : public I, public RefCounted<B>;  // B specific implementation
+// 4. Smart pointers here are very bad candidates for function parameters.  Use
+//    dumb pointers in function parameter list.
+// 5. When down_cast is performed on a dangling pointer due to bugs in code,
+//    VC++ will generate SEH which is not handled well in VC++ debugger.  One
+//    can use WinDBG to run it and get the faulting stack.
+// 6. Idioms for heap object as return value
+//    Foo* createFoo() { FooPtr obj = new Foo(); return obj.Detach(); }
+//    Foo* passthru() { FooPtr obj = createFoo(), return obj; }
+//    FooPtr end_scope_pointer;
+//    end_scope_pointer.Attach(passThrough);
+//    If you are not passing that object back, you are the end of scope.
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_PORT_REFCOUNT_H_
+#define SFNTLY_CPP_SRC_SFNTLY_PORT_REFCOUNT_H_
+
+#if !defined (NDEBUG)
+  #define ENABLE_OBJECT_COUNTER
+//  #define REF_COUNT_DEBUGGING
+#endif
+
+#if defined (REF_COUNT_DEBUGGING)
+  #include <stdio.h>
+  #include <typeinfo>
+#endif
+
+#include "sfntly/port/atomic.h"
+#include "sfntly/port/type.h"
+
+// Special tag for functions that requires caller to attach instead of using
+// assignment operators.
+#define CALLER_ATTACH
+
+#if defined (REF_COUNT_DEBUGGING)
+  #define DEBUG_OUTPUT(a) \
+      fprintf(stderr, "%s%s:oc=%d,oid=%d,rc=%d\n", a, \
+              typeid(this).name(), object_counter_, object_id_, ref_count_)
+#else
+  #define DEBUG_OUTPUT(a)
+#endif
+
+#if defined (_MSC_VER)
+  // VC 2008/2010 incorrectly gives this warning for pure virtual functions
+  // in virtual inheritance.  The only way to get around it is to disable it.
+  #pragma warning(disable:4250)
+#endif
+
+namespace sfntly {
+
+class RefCount {
+ public:
+  // Make gcc -Wnon-virtual-dtor happy.
+  virtual ~RefCount() {}
+
+  virtual size_t AddRef() const = 0;
+  virtual size_t Release() const = 0;
+};
+
+template <typename T>
+class NoAddRefRelease : public T {
+ public:
+  NoAddRefRelease();
+  ~NoAddRefRelease();
+
+ private:
+  virtual size_t AddRef() const = 0;
+  virtual size_t Release() const = 0;
+};
+
+template <typename TDerived>
+class RefCounted : virtual public RefCount {
+ public:
+  RefCounted() : ref_count_(0) {
+#if defined (ENABLE_OBJECT_COUNTER)
+    object_id_ = AtomicIncrement(&next_id_);
+    AtomicIncrement(&object_counter_);
+    DEBUG_OUTPUT("C ");
+#endif
+  }
+  RefCounted(const RefCounted<TDerived>&) : ref_count_(0) {}
+  virtual ~RefCounted() {
+#if defined (ENABLE_OBJECT_COUNTER)
+    AtomicDecrement(&object_counter_);
+    DEBUG_OUTPUT("D ");
+#endif
+  }
+
+  RefCounted<TDerived>& operator=(const RefCounted<TDerived>&) {
+    // Each object maintains own ref count, don't propagate.
+    return *this;
+  }
+
+  virtual size_t AddRef() const {
+    size_t new_count = AtomicIncrement(&ref_count_);
+    DEBUG_OUTPUT("A ");
+    return new_count;
+  }
+
+  virtual size_t Release() const {
+    size_t new_ref_count = AtomicDecrement(&ref_count_);
+    DEBUG_OUTPUT("R ");
+    if (new_ref_count == 0) {
+      // A C-style is used to cast away const-ness and to derived.
+      // lint does not like this but this is how it works.
+      delete (TDerived*)(this);
+    }
+    return new_ref_count;
+  }
+
+  mutable size_t ref_count_;  // reference count of current object
+#if defined (ENABLE_OBJECT_COUNTER)
+  static size_t object_counter_;
+  static size_t next_id_;
+  mutable size_t object_id_;
+#endif
+};
+
+#if defined (ENABLE_OBJECT_COUNTER)
+template <typename TDerived> size_t RefCounted<TDerived>::object_counter_ = 0;
+template <typename TDerived> size_t RefCounted<TDerived>::next_id_ = 0;
+#endif
+
+// semi-smart pointer for RefCount derived objects, similar to CComPtr
+template <typename T>
+class Ptr {
+ public:
+  Ptr() : p_(NULL) {
+  }
+
+  // This constructor shall not be explicit.
+  // lint does not like this but this is how it works.
+  Ptr(T* pT) : p_(NULL) {
+    *this = pT;
+  }
+
+  Ptr(const Ptr<T>& p) : p_(NULL) {
+    *this = p;
+  }
+
+  ~Ptr() {
+    Release();
+  }
+
+  T* operator=(T* pT) {
+    if (p_ == pT) {
+      return p_;
+    }
+    if (pT) {
+      RefCount* p = static_cast<RefCount*>(pT);
+      if (p == NULL) {
+        return NULL;
+      }
+      p->AddRef();  // always AddRef() before Release()
+    }
+    Release();
+    p_ = pT;
+    return p_;
+  }
+
+  T* operator=(const Ptr<T>& p) {
+    if (p_ == p.p_) {
+      return p_;
+    }
+    return operator=(p.p_);
+  }
+
+  operator T*&() {
+    return p_;
+  }
+
+  T& operator*() const {
+    return *p_;  // It can throw!
+  }
+
+  NoAddRefRelease<T>* operator->() const {
+    return (NoAddRefRelease<T>*)p_;  // It can throw!
+  }
+
+  bool operator!() const {
+    return (p_ == NULL);
+  }
+
+  bool operator<(const Ptr<T>& p) const {
+    return (p_ < p.p_);
+  }
+
+  bool operator!=(T* pT) const {
+    return !operator==(pT);
+  }
+
+  bool operator==(T* pT) const {
+    return (p_ == pT);
+  }
+
+  size_t Release() const {
+    size_t ref_count = 0;
+    if (p_) {
+      RefCount* p = static_cast<RefCount*>(p_);
+      if (p) {
+        ref_count = p->Release();
+      }
+      p_ = NULL;
+    }
+    return ref_count;
+  }
+
+  void Attach(T* pT) {
+    if (p_ != pT) {
+      Release();
+      p_ = pT;
+    }
+  }
+
+  T* Detach() {
+    T* pT = p_;
+    p_ = NULL;
+    return pT;
+  }
+
+  mutable T* p_;
+};
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_PORT_REFCOUNT_H_
diff --git a/sfntly/port/type.h b/sfntly/port/type.h
new file mode 100644
index 0000000..20a5ba8
--- /dev/null
+++ b/sfntly/port/type.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_PORT_TYPE_H_
+#define SFNTLY_CPP_SRC_SFNTLY_PORT_TYPE_H_
+
+#include <assert.h>
+
+#if defined (_MSC_VER) && (_MSC_VER < 1600)
+  typedef unsigned char     uint8_t;
+  typedef signed char       int8_t;
+  typedef unsigned __int16  uint16_t;
+  typedef signed __int16    int16_t;
+  typedef unsigned __int32  uint32_t;
+  typedef signed __int32    int32_t;
+  typedef unsigned __int64  uint64_t;
+  typedef signed __int64    int64_t;
+  // Definitions to avoid ICU redefinition issue
+  #define U_HAVE_INT8_T 1
+  #define U_HAVE_UINT8_T 1
+  #define U_HAVE_INT16_T 1
+  #define U_HAVE_UINT16_T 1
+  #define U_HAVE_INT32_T 1
+  #define U_HAVE_UINT32_T 1
+  #define U_HAVE_INT64_T 1
+  #define U_HAVE_UINT64_T 1
+#else
+  #include <stdint.h>
+#endif
+
+#include <cstddef>
+#include <vector>
+#include <set>
+
+namespace sfntly {
+
+typedef uint8_t   byte_t;
+typedef uint16_t  word_t;
+typedef uint32_t  dword_t;
+typedef uint64_t  qword_t;
+
+typedef std::vector<byte_t> ByteVector;
+typedef std::vector<int32_t> IntegerList;
+typedef std::set<int32_t> IntegerSet;
+
+// A macro to disallow the copy constructor and operator= functions.
+// This should be used in the private: declarations for a class.
+#define NO_COPY_AND_ASSIGN(TypeName) \
+  TypeName(const TypeName&);               \
+  void operator=(const TypeName&)
+
+}  // namespace sfntly
+
+// Make google3 happy since it prohibits RTTI.
+template<typename To, typename From>
+inline To implicit_cast(From const &f) {
+  return f;
+}
+
+template<typename To, typename From>     // use like this: down_cast<T*>(foo);
+inline To down_cast(From* f) {                   // so we only accept pointers
+  // Ensures that To is a sub-type of From *.  This test is here only
+  // for compile-time type checking, and has no overhead in an
+  // optimized build at run-time, as it will be optimized away
+  // completely.
+#if defined (_MSC_VER)
+  #pragma warning(push)
+  #pragma warning(disable:4127)  // disable "conditional expression is constant"
+#endif
+  if (false) {
+    implicit_cast<From*, To>(0);
+  }
+#if defined (_MSC_VER)
+  #pragma warning(pop)
+#endif
+
+// The following code is the only place for RTTI.  It is done so to allow
+// additional type checking when SFNTLY_TYPE_VERIFICATION is defined.
+#if defined (SFNTLY_TYPE_VERIFICATION)
+  assert(f == NULL || dynamic_cast<To>(f) != NULL);
+#endif
+  return static_cast<To>(f);
+}
+
+#if !defined(WIN32)
+  #define UNREFERENCED_PARAMETER(p) do { (void)p; } while (0)
+#endif
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_PORT_TYPE_H_
diff --git a/sfntly/table/bitmap/big_glyph_metrics.cc b/sfntly/table/bitmap/big_glyph_metrics.cc
new file mode 100644
index 0000000..d853212
--- /dev/null
+++ b/sfntly/table/bitmap/big_glyph_metrics.cc
@@ -0,0 +1,171 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/table/bitmap/big_glyph_metrics.h"
+
+namespace sfntly {
+/******************************************************************************
+ * BigGlyphMetrics class
+ ******************************************************************************/
+BigGlyphMetrics::BigGlyphMetrics(ReadableFontData* data)
+    : GlyphMetrics(data) {
+}
+
+BigGlyphMetrics::~BigGlyphMetrics() {
+}
+
+int32_t BigGlyphMetrics::Height() {
+  return data_->ReadByte(Offset::kHeight);
+}
+
+int32_t BigGlyphMetrics::Width() {
+  return data_->ReadByte(Offset::kWidth);
+}
+
+int32_t BigGlyphMetrics::HoriBearingX() {
+  return data_->ReadByte(Offset::kHoriBearingX);
+}
+
+int32_t BigGlyphMetrics::HoriBearingY() {
+  return data_->ReadByte(Offset::kHoriBearingY);
+}
+
+int32_t BigGlyphMetrics::HoriAdvance() {
+  return data_->ReadByte(Offset::kHoriAdvance);
+}
+
+int32_t BigGlyphMetrics::VertBearingX() {
+  return data_->ReadByte(Offset::kVertBearingX);
+}
+
+int32_t BigGlyphMetrics::VertBearingY() {
+  return data_->ReadByte(Offset::kVertBearingY);
+}
+
+int32_t BigGlyphMetrics::VertAdvance() {
+  return data_->ReadByte(Offset::kVertAdvance);
+}
+
+/******************************************************************************
+ * BigGlyphMetrics::Builder class
+ ******************************************************************************/
+BigGlyphMetrics::Builder::Builder(WritableFontData* data)
+    : GlyphMetrics::Builder(data) {
+}
+
+BigGlyphMetrics::Builder::Builder(ReadableFontData* data)
+    : GlyphMetrics::Builder(data) {
+}
+
+BigGlyphMetrics::Builder::~Builder() {
+}
+
+int32_t BigGlyphMetrics::Builder::Height() {
+  return InternalReadData()->ReadByte(Offset::kHeight);
+}
+
+void BigGlyphMetrics::Builder::SetHeight(byte_t height) {
+  InternalWriteData()->WriteByte(Offset::kHeight, height);
+}
+
+int32_t BigGlyphMetrics::Builder::Width() {
+  return InternalReadData()->ReadByte(Offset::kWidth);
+}
+
+void BigGlyphMetrics::Builder::SetWidth(byte_t width) {
+  InternalWriteData()->WriteByte(Offset::kWidth, width);
+}
+
+int32_t BigGlyphMetrics::Builder::HoriBearingX() {
+  return InternalReadData()->ReadByte(Offset::kHoriBearingX);
+}
+
+void BigGlyphMetrics::Builder::SetHoriBearingX(byte_t bearing) {
+  InternalWriteData()->WriteByte(Offset::kHoriBearingX, bearing);
+}
+
+int32_t BigGlyphMetrics::Builder::HoriBearingY() {
+  return InternalReadData()->ReadByte(Offset::kHoriBearingY);
+}
+
+void BigGlyphMetrics::Builder::SetHoriBearingY(byte_t bearing) {
+  InternalWriteData()->WriteByte(Offset::kHoriBearingY, bearing);
+}
+
+int32_t BigGlyphMetrics::Builder::HoriAdvance() {
+  return InternalReadData()->ReadByte(Offset::kHoriAdvance);
+}
+
+void BigGlyphMetrics::Builder::SetHoriAdvance(byte_t advance) {
+  InternalWriteData()->WriteByte(Offset::kHoriAdvance, advance);
+}
+
+int32_t BigGlyphMetrics::Builder::VertBearingX() {
+  return InternalReadData()->ReadByte(Offset::kVertBearingX);
+}
+
+void BigGlyphMetrics::Builder::SetVertBearingX(byte_t bearing) {
+  InternalWriteData()->WriteByte(Offset::kVertBearingX, bearing);
+}
+
+int32_t BigGlyphMetrics::Builder::VertBearingY() {
+  return InternalReadData()->ReadByte(Offset::kVertBearingY);
+}
+
+void BigGlyphMetrics::Builder::SetVertBearingY(byte_t bearing) {
+  InternalWriteData()->WriteByte(Offset::kVertBearingY, bearing);
+}
+
+int32_t BigGlyphMetrics::Builder::VertAdvance() {
+  return InternalReadData()->ReadByte(Offset::kVertAdvance);
+}
+
+void BigGlyphMetrics::Builder::SetVertAdvance(byte_t advance) {
+  InternalWriteData()->WriteByte(Offset::kVertAdvance, advance);
+}
+
+CALLER_ATTACH FontDataTable*
+    BigGlyphMetrics::Builder::SubBuildTable(ReadableFontData* data) {
+  BigGlyphMetricsPtr output = new BigGlyphMetrics(data);
+  return output.Detach();
+}
+
+void BigGlyphMetrics::Builder::SubDataSet() {
+  // NOP.
+}
+
+int32_t BigGlyphMetrics::Builder::SubDataSizeToSerialize() {
+  return 0;
+}
+
+bool BigGlyphMetrics::Builder::SubReadyToSerialize() {
+  return false;
+}
+
+int32_t BigGlyphMetrics::Builder::SubSerialize(WritableFontData* new_data) {
+  return Data()->CopyTo(new_data);
+}
+
+// static
+CALLER_ATTACH
+BigGlyphMetrics::Builder* BigGlyphMetrics::Builder::CreateBuilder() {
+  WritableFontDataPtr data;
+  data.Attach(WritableFontData::CreateWritableFontData(Offset::kMetricsLength));
+  BigGlyphMetricsBuilderPtr output = new BigGlyphMetrics::Builder(data);
+  return output.Detach();
+}
+
+}  // namespace sfntly
diff --git a/sfntly/table/bitmap/big_glyph_metrics.h b/sfntly/table/bitmap/big_glyph_metrics.h
new file mode 100644
index 0000000..a91601c
--- /dev/null
+++ b/sfntly/table/bitmap/big_glyph_metrics.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_BIG_GLYPH_METRICS_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_BIG_GLYPH_METRICS_H_
+
+#include "sfntly/table/bitmap/glyph_metrics.h"
+
+namespace sfntly {
+
+class BigGlyphMetrics : public GlyphMetrics,
+                        public RefCounted<BigGlyphMetrics> {
+ public:
+  struct Offset {
+    enum {
+      kMetricsLength = 8,
+
+      kHeight = 0,
+      kWidth = 1,
+      kHoriBearingX = 2,
+      kHoriBearingY = 3,
+      kHoriAdvance = 4,
+      kVertBearingX = 5,
+      kVertBearingY = 6,
+      kVertAdvance = 7,
+    };
+  };
+
+  class Builder : public GlyphMetrics::Builder,
+                  public RefCounted<Builder> {
+   public:
+    // Constructor scope altered to public because C++ does not allow base
+    // class to instantiate derived class with protected constructors.
+    explicit Builder(WritableFontData* data);
+    explicit Builder(ReadableFontData* data);
+
+    virtual ~Builder();
+
+    int32_t Height();
+    void SetHeight(byte_t height);
+    int32_t Width();
+    void SetWidth(byte_t width);
+    int32_t HoriBearingX();
+    void SetHoriBearingX(byte_t bearing);
+    int32_t HoriBearingY();
+    void SetHoriBearingY(byte_t bearing);
+    int32_t HoriAdvance();
+    void SetHoriAdvance(byte_t advance);
+    int32_t VertBearingX();
+    void SetVertBearingX(byte_t bearing);
+    int32_t VertBearingY();
+    void SetVertBearingY(byte_t bearing);
+    int32_t VertAdvance();
+    void SetVertAdvance(byte_t advance);
+
+    virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+    virtual void SubDataSet();
+    virtual int32_t SubDataSizeToSerialize();
+    virtual bool SubReadyToSerialize();
+    virtual int32_t SubSerialize(WritableFontData* new_data);
+
+    // Static instantiation function.
+    static CALLER_ATTACH Builder* CreateBuilder();
+  };
+
+  explicit BigGlyphMetrics(ReadableFontData* data);
+  virtual ~BigGlyphMetrics();
+
+  int32_t Height();
+  int32_t Width();
+  int32_t HoriBearingX();
+  int32_t HoriBearingY();
+  int32_t HoriAdvance();
+  int32_t VertBearingX();
+  int32_t VertBearingY();
+  int32_t VertAdvance();
+};
+typedef Ptr<BigGlyphMetrics> BigGlyphMetricsPtr;
+typedef Ptr<BigGlyphMetrics::Builder> BigGlyphMetricsBuilderPtr;
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_BIG_GLYPH_METRICS_H_
diff --git a/sfntly/table/bitmap/bitmap_glyph.cc b/sfntly/table/bitmap/bitmap_glyph.cc
new file mode 100644
index 0000000..334a0c0
--- /dev/null
+++ b/sfntly/table/bitmap/bitmap_glyph.cc
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/table/bitmap/bitmap_glyph.h"
+#include "sfntly/table/bitmap/simple_bitmap_glyph.h"
+#include "sfntly/table/bitmap/composite_bitmap_glyph.h"
+
+namespace sfntly {
+/******************************************************************************
+ * BitmapGlyph class
+ ******************************************************************************/
+BitmapGlyph::~BitmapGlyph() {
+}
+
+CALLER_ATTACH BitmapGlyph* BitmapGlyph::CreateGlyph(ReadableFontData* data,
+                                                    int32_t format) {
+  BitmapGlyphPtr glyph;
+  BitmapGlyphBuilderPtr builder;
+  builder.Attach(Builder::CreateGlyphBuilder(data, format));
+  if (builder) {
+    glyph.Attach(down_cast<BitmapGlyph*>(builder->Build()));
+  }
+  return glyph;
+}
+
+BitmapGlyph::BitmapGlyph(ReadableFontData* data, int32_t format)
+    : SubTable(data), format_(format) {
+}
+
+/******************************************************************************
+ * BitmapGlyph::Builder class
+ ******************************************************************************/
+BitmapGlyph::Builder::~Builder() {
+}
+
+CALLER_ATTACH BitmapGlyph::Builder*
+BitmapGlyph::Builder::CreateGlyphBuilder(ReadableFontData* data,
+                                         int32_t format) {
+  BitmapGlyphBuilderPtr builder;
+  switch (format) {
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+    case 6:
+    case 7:
+      builder = new SimpleBitmapGlyph::Builder(data, format);
+      break;
+    case 8:
+    case 9:
+      builder = new CompositeBitmapGlyph::Builder(data, format);
+      break;
+  }
+  return builder.Detach();
+}
+
+BitmapGlyph::Builder::Builder(WritableFontData* data, int32_t format)
+    : SubTable::Builder(data), format_(format) {
+}
+
+BitmapGlyph::Builder::Builder(ReadableFontData* data, int32_t format)
+    : SubTable::Builder(data), format_(format) {
+}
+
+CALLER_ATTACH
+FontDataTable* BitmapGlyph::Builder::SubBuildTable(ReadableFontData* data) {
+  UNREFERENCED_PARAMETER(data);
+  return NULL;
+}
+
+void BitmapGlyph::Builder::SubDataSet() {
+  // NOP
+}
+
+int32_t BitmapGlyph::Builder::SubDataSizeToSerialize() {
+  return InternalReadData()->Length();
+}
+
+bool BitmapGlyph::Builder::SubReadyToSerialize() {
+  return true;
+}
+
+int32_t BitmapGlyph::Builder::SubSerialize(WritableFontData* new_data) {
+  return InternalReadData()->CopyTo(new_data);
+}
+
+}  // namespace sfntly
diff --git a/sfntly/table/bitmap/bitmap_glyph.h b/sfntly/table/bitmap/bitmap_glyph.h
new file mode 100644
index 0000000..2dd4c3a
--- /dev/null
+++ b/sfntly/table/bitmap/bitmap_glyph.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_BITMAP_GLYPH_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_BITMAP_GLYPH_H_
+
+#include <vector>
+#include <map>
+
+#include "sfntly/table/subtable.h"
+
+namespace sfntly {
+
+class BitmapGlyph : public SubTable {
+ public:
+  struct Offset {
+    enum {
+      // header
+      kVersion = 0,
+
+      kSmallGlyphMetricsLength = 5,
+      kBigGlyphMetricsLength = 8,
+      // format 1
+      kGlyphFormat1_imageData = kSmallGlyphMetricsLength,
+
+      // format 2
+      kGlyphFormat2_imageData = kSmallGlyphMetricsLength,
+
+      // format 3
+
+      // format 4
+
+      // format 5
+      kGlyphFormat5_imageData = 0,
+
+      // format 6
+      kGlyphFormat6_imageData = kBigGlyphMetricsLength,
+
+      // format 7
+      kGlyphFormat7_imageData = kBigGlyphMetricsLength,
+
+      // format 8
+      kGlyphFormat8_numComponents = kSmallGlyphMetricsLength + 1,
+      kGlyphFormat8_componentArray = kGlyphFormat8_numComponents +
+                                     DataSize::kUSHORT,
+
+      // format 9
+      kGlyphFormat9_numComponents = kBigGlyphMetricsLength,
+      kGlyphFormat9_componentArray = kGlyphFormat9_numComponents +
+                                     DataSize::kUSHORT,
+
+      // ebdtComponent
+      kEbdtComponentLength = DataSize::kUSHORT + 2 * DataSize::kCHAR,
+      kEbdtComponent_glyphCode = 0,
+      kEbdtComponent_xOffset = 2,
+      kEbdtComponent_yOffset = 3,
+    };
+  };
+
+  // TODO(stuartg): builder is not functional at all
+  // - need to add subclasses for each type of bitmap glyph
+  class Builder : public SubTable::Builder {
+   public:
+    virtual ~Builder();
+
+    virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+    virtual void SubDataSet();
+    virtual int32_t SubDataSizeToSerialize();
+    virtual bool SubReadyToSerialize();
+    virtual int32_t SubSerialize(WritableFontData* new_data);
+
+    int32_t format() { return format_; }
+
+    static CALLER_ATTACH Builder* CreateGlyphBuilder(ReadableFontData* data,
+                                                     int32_t format);
+
+   protected:
+    Builder(WritableFontData* data, int32_t format);
+    Builder(ReadableFontData* data, int32_t format);
+
+   private:
+    int32_t format_;
+  };
+
+  virtual ~BitmapGlyph();
+
+  static CALLER_ATTACH BitmapGlyph* CreateGlyph(ReadableFontData* data,
+                                                int32_t format);
+  int32_t format() { return format_; }
+
+  // UNIMPLEMENTED: toString()
+
+ protected:
+  BitmapGlyph(ReadableFontData* data, int32_t format);
+
+ private:
+  int32_t format_;
+};
+typedef Ptr<BitmapGlyph> BitmapGlyphPtr;
+typedef Ptr<BitmapGlyph::Builder> BitmapGlyphBuilderPtr;
+typedef std::map<int32_t, BitmapGlyphBuilderPtr> BitmapGlyphBuilderMap;
+typedef std::vector<BitmapGlyphBuilderMap> BitmapGlyphBuilderList;
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_BITMAP_GLYPH_H_
diff --git a/sfntly/table/bitmap/bitmap_glyph_info.cc b/sfntly/table/bitmap/bitmap_glyph_info.cc
new file mode 100644
index 0000000..ab9953b
--- /dev/null
+++ b/sfntly/table/bitmap/bitmap_glyph_info.cc
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/table/bitmap/bitmap_glyph_info.h"
+
+namespace sfntly {
+
+BitmapGlyphInfo::BitmapGlyphInfo(int32_t glyph_id,
+                                 int32_t block_offset,
+                                 int32_t start_offset,
+                                 int32_t length,
+                                 int32_t format)
+    : glyph_id_(glyph_id),
+      relative_(true),
+      block_offset_(block_offset),
+      start_offset_(start_offset),
+      length_(length),
+      format_(format) {
+}
+
+BitmapGlyphInfo::BitmapGlyphInfo(int32_t glyph_id,
+                                 int32_t start_offset,
+                                 int32_t length,
+                                 int32_t format)
+    : glyph_id_(glyph_id),
+      relative_(false),
+      block_offset_(0),
+      start_offset_(start_offset),
+      length_(length),
+      format_(format) {
+}
+
+bool BitmapGlyphInfo::operator==(const BitmapGlyphInfo& rhs) const {
+  return (format_ == rhs.format_ &&
+          glyph_id_ == rhs.glyph_id_ &&
+          length_ == rhs.length_ &&
+          offset() == rhs.offset());
+}
+
+bool BitmapGlyphInfo::operator==(BitmapGlyphInfo* rhs) {
+  if (rhs == NULL) {
+    return this == NULL;
+  }
+  return (format_ == rhs->format() &&
+          glyph_id_ == rhs->glyph_id() &&
+          length_ == rhs->length() &&
+          offset() == rhs->offset());
+}
+
+bool StartOffsetComparator::operator()(BitmapGlyphInfo* lhs,
+                                       BitmapGlyphInfo* rhs) {
+  return lhs->start_offset() > rhs->start_offset();
+}
+
+}  // namespace sfntly
diff --git a/sfntly/table/bitmap/bitmap_glyph_info.h b/sfntly/table/bitmap/bitmap_glyph_info.h
new file mode 100644
index 0000000..9921d0d
--- /dev/null
+++ b/sfntly/table/bitmap/bitmap_glyph_info.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_GLYPH_INFO_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_GLYPH_INFO_H_
+
+#include <vector>
+#include <map>
+
+#include "sfntly/table/subtable.h"
+
+namespace sfntly {
+
+// An immutable class holding bitmap glyph information.
+class BitmapGlyphInfo : public RefCounted<BitmapGlyphInfo> {
+ public:
+  // Constructor for a relative located glyph. The glyph's position in the EBDT
+  // table is a combination of it's block offset and it's own start offset.
+  // @param glyphId the glyph id
+  // @param blockOffset the offset of the block to which the glyph belongs
+  // @param startOffset the offset of the glyph within the block
+  // @param length the byte length
+  // @param format the glyph image format
+  BitmapGlyphInfo(int32_t glyph_id,
+                  int32_t block_offset,
+                  int32_t start_offset,
+                  int32_t length,
+                  int32_t format);
+
+  // Constructor for an absolute located glyph. The glyph's position in the EBDT
+  // table is only given by it's own start offset.
+  // @param glyphId the glyph id
+  // @param startOffset the offset of the glyph within the block
+  // @param length the byte length
+  // @param format the glyph image format
+  BitmapGlyphInfo(int32_t glyph_id,
+                  int32_t start_offset,
+                  int32_t length,
+                  int32_t format);
+
+  int32_t glyph_id() const { return glyph_id_; }
+  bool relative() const { return relative_; }
+  int32_t block_offset() const { return block_offset_; }
+  int32_t offset() const { return block_offset() + start_offset(); }
+  int32_t start_offset() const { return start_offset_; }
+  int32_t length() const { return length_; }
+  int32_t format() const { return format_; }
+
+  // UNIMPLEMENTED: hashCode()
+  bool operator==(const BitmapGlyphInfo& rhs) const;
+  bool operator==(BitmapGlyphInfo* rhs);
+
+ private:
+  int32_t glyph_id_;
+  bool relative_;
+  int32_t block_offset_;
+  int32_t start_offset_;
+  int32_t length_;
+  int32_t format_;
+};
+typedef Ptr<BitmapGlyphInfo> BitmapGlyphInfoPtr;
+typedef std::map<int32_t, BitmapGlyphInfoPtr> BitmapGlyphInfoMap;
+typedef std::vector<BitmapGlyphInfoMap> BitmapLocaList;
+
+class StartOffsetComparator {
+ public:
+  bool operator()(BitmapGlyphInfo* lhs, BitmapGlyphInfo* rhs);
+};
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_GLYPH_INFO_H_
diff --git a/sfntly/table/bitmap/bitmap_size_table.cc b/sfntly/table/bitmap/bitmap_size_table.cc
new file mode 100644
index 0000000..6c7d731
--- /dev/null
+++ b/sfntly/table/bitmap/bitmap_size_table.cc
@@ -0,0 +1,604 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/table/bitmap/bitmap_size_table.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "sfntly/math/font_math.h"
+#include "sfntly/table/bitmap/eblc_table.h"
+#include "sfntly/table/bitmap/index_sub_table_format1.h"
+#include "sfntly/table/bitmap/index_sub_table_format2.h"
+#include "sfntly/table/bitmap/index_sub_table_format3.h"
+#include "sfntly/table/bitmap/index_sub_table_format4.h"
+#include "sfntly/table/bitmap/index_sub_table_format5.h"
+
+namespace sfntly {
+/******************************************************************************
+ * BitmapSizeTable class
+ ******************************************************************************/
+BitmapSizeTable::~BitmapSizeTable() {
+}
+
+int32_t BitmapSizeTable::IndexSubTableArrayOffset() {
+  return data_->ReadULongAsInt(
+      EblcTable::Offset::kBitmapSizeTable_indexSubTableArrayOffset);
+}
+
+int32_t BitmapSizeTable::IndexTableSize() {
+  return data_->ReadULongAsInt(
+      EblcTable::Offset::kBitmapSizeTable_indexTableSize);
+}
+
+int32_t BitmapSizeTable::NumberOfIndexSubTables() {
+  return NumberOfIndexSubTables(data_, 0);
+}
+
+int32_t BitmapSizeTable::ColorRef() {
+  return data_->ReadULongAsInt(EblcTable::Offset::kBitmapSizeTable_colorRef);
+}
+
+int32_t BitmapSizeTable::StartGlyphIndex() {
+  return data_->ReadUShort(EblcTable::Offset::kBitmapSizeTable_startGlyphIndex);
+}
+
+int32_t BitmapSizeTable::EndGlyphIndex() {
+  return data_->ReadUShort(EblcTable::Offset::kBitmapSizeTable_endGlyphIndex);
+}
+
+int32_t BitmapSizeTable::PpemX() {
+  return data_->ReadByte(EblcTable::Offset::kBitmapSizeTable_ppemX);
+}
+
+int32_t BitmapSizeTable::PpemY() {
+  return data_->ReadByte(EblcTable::Offset::kBitmapSizeTable_ppemY);
+}
+
+int32_t BitmapSizeTable::BitDepth() {
+  return data_->ReadByte(EblcTable::Offset::kBitmapSizeTable_bitDepth);
+}
+
+int32_t BitmapSizeTable::FlagsAsInt() {
+  return data_->ReadChar(EblcTable::Offset::kBitmapSizeTable_flags);
+}
+
+IndexSubTable* BitmapSizeTable::GetIndexSubTable(int32_t index) {
+  IndexSubTableList* subtable_list = GetIndexSubTableList();
+  if (index >= 0 && (size_t)index < subtable_list->size()) {
+    return (*subtable_list)[index];
+  }
+  return NULL;
+}
+
+int32_t BitmapSizeTable::GlyphOffset(int32_t glyph_id) {
+  IndexSubTable* subtable = SearchIndexSubTables(glyph_id);
+  if (subtable == NULL) {
+    return -1;
+  }
+  return subtable->GlyphOffset(glyph_id);
+}
+
+int32_t BitmapSizeTable::GlyphLength(int32_t glyph_id) {
+  IndexSubTable* subtable = SearchIndexSubTables(glyph_id);
+  if (subtable == NULL) {
+    return -1;
+  }
+  return subtable->GlyphLength(glyph_id);
+}
+
+CALLER_ATTACH BitmapGlyphInfo* BitmapSizeTable::GlyphInfo(int32_t glyph_id) {
+  IndexSubTable* sub_table = SearchIndexSubTables(glyph_id);
+  if (sub_table == NULL) {
+    return NULL;
+  }
+  return sub_table->GlyphInfo(glyph_id);
+}
+
+int32_t BitmapSizeTable::GlyphFormat(int32_t glyph_id) {
+  IndexSubTable* subtable = SearchIndexSubTables(glyph_id);
+  if (subtable == NULL) {
+    return -1;
+  }
+  return subtable->image_format();
+}
+
+BitmapSizeTable::BitmapSizeTable(ReadableFontData* data,
+                                 ReadableFontData* master_data)
+    : SubTable(data, master_data) {
+}
+
+// static
+int32_t BitmapSizeTable::NumberOfIndexSubTables(ReadableFontData* data,
+                                                int32_t table_offset) {
+  return data->ReadULongAsInt(table_offset +
+      EblcTable::Offset::kBitmapSizeTable_numberOfIndexSubTables);
+}
+
+IndexSubTable* BitmapSizeTable::SearchIndexSubTables(int32_t glyph_id) {
+  // would be faster to binary search but too many size tables don't have
+  // sorted subtables
+#if (SFNTLY_BITMAPSIZE_USE_BINARY_SEARCH)
+  return BinarySearchIndexSubTables(glyph_id);
+#else
+  return LinearSearchIndexSubTables(glyph_id);
+#endif
+}
+
+IndexSubTable* BitmapSizeTable::LinearSearchIndexSubTables(int32_t glyph_id) {
+  IndexSubTableList* subtable_list = GetIndexSubTableList();
+  for (IndexSubTableList::iterator b = subtable_list->begin(),
+                                   e = subtable_list->end(); b != e; b++) {
+    if ((*b)->first_glyph_index() <= glyph_id &&
+        (*b)->last_glyph_index() >= glyph_id) {
+      return *b;
+    }
+  }
+  return NULL;
+}
+
+IndexSubTable* BitmapSizeTable::BinarySearchIndexSubTables(int32_t glyph_id) {
+  IndexSubTableList* subtable_list = GetIndexSubTableList();
+  int32_t index = 0;
+  int32_t bottom = 0;
+  int32_t top = subtable_list->size();
+  while (top != bottom) {
+    index = (top + bottom) / 2;
+    IndexSubTable* subtable = (*subtable_list)[index];
+    if (glyph_id < subtable->first_glyph_index()) {
+      // Location beow current location
+      top = index;
+    } else {
+      if (glyph_id <= subtable->last_glyph_index()) {
+        return subtable;
+      } else {
+        bottom = index + 1;
+      }
+    }
+  }
+  return NULL;
+}
+
+CALLER_ATTACH
+IndexSubTable* BitmapSizeTable::CreateIndexSubTable(int32_t index) {
+  return IndexSubTable::CreateIndexSubTable(master_read_data(),
+                                            IndexSubTableArrayOffset(),
+                                            index);
+}
+
+IndexSubTableList* BitmapSizeTable::GetIndexSubTableList() {
+  AutoLock lock(index_subtables_lock_);
+  if (index_subtables_.empty()) {
+    for (int32_t i = 0; i < NumberOfIndexSubTables(); ++i) {
+      IndexSubTablePtr table;
+      table.Attach(CreateIndexSubTable(i));
+      index_subtables_.push_back(table);
+    }
+  }
+  return &index_subtables_;
+}
+
+/******************************************************************************
+ * BitmapSizeTable::Builder class
+ ******************************************************************************/
+BitmapSizeTable::Builder::~Builder() {
+}
+
+CALLER_ATTACH
+FontDataTable* BitmapSizeTable::Builder::SubBuildTable(ReadableFontData* data) {
+  BitmapSizeTablePtr output = new BitmapSizeTable(data, master_read_data());
+  return output.Detach();
+}
+
+void BitmapSizeTable::Builder::SubDataSet() {
+  Revert();
+}
+
+int32_t BitmapSizeTable::Builder::SubDataSizeToSerialize() {
+  IndexSubTableBuilderList* builders = IndexSubTableBuilders();
+  if (builders->empty()) {
+    return 0;
+  }
+  int32_t size = EblcTable::Offset::kBitmapSizeTableLength;
+  bool variable = false;
+  for (IndexSubTableBuilderList::iterator b = builders->begin(),
+                                          e = builders->end(); b != e; b++) {
+    size += EblcTable::Offset::kIndexSubTableEntryLength;
+    int32_t sub_table_size = (*b)->SubDataSizeToSerialize();
+    int32_t padding = FontMath::PaddingRequired(abs(sub_table_size),
+                                                DataSize::kULONG);
+#if defined (SFNTLY_DEBUG_BITMAP)
+    fprintf(stderr, "subtable size=%d\n", sub_table_size);
+#endif
+    variable = (sub_table_size > 0) ? variable : true;
+    size += abs(sub_table_size) + padding;
+  }
+#if defined (SFNTLY_DEBUG_BITMAP)
+  fprintf(stderr, "bitmap table size=%d\n", variable ? -size : size);
+#endif
+  return variable ? -size : size;
+}
+
+bool BitmapSizeTable::Builder::SubReadyToSerialize() {
+  if (IndexSubTableBuilders()->empty()) {
+    return false;
+  }
+  return true;
+}
+
+int32_t BitmapSizeTable::Builder::SubSerialize(WritableFontData* new_data) {
+  SetNumberOfIndexSubTables(IndexSubTableBuilders()->size());
+  int32_t size = InternalReadData()->CopyTo(new_data);
+  return size;
+}
+
+CALLER_ATTACH BitmapSizeTable::Builder*
+BitmapSizeTable::Builder::CreateBuilder(WritableFontData* data,
+                                        ReadableFontData* master_data) {
+  BitmapSizeTableBuilderPtr output =
+      new BitmapSizeTable::Builder(data, master_data);
+  return output.Detach();
+}
+
+CALLER_ATTACH BitmapSizeTable::Builder*
+BitmapSizeTable::Builder::CreateBuilder(ReadableFontData* data,
+                                        ReadableFontData* master_data) {
+  BitmapSizeTableBuilderPtr output =
+      new BitmapSizeTable::Builder(data, master_data);
+  return output.Detach();
+}
+
+int32_t BitmapSizeTable::Builder::IndexSubTableArrayOffset() {
+  return InternalReadData()->ReadULongAsInt(
+      EblcTable::Offset::kBitmapSizeTable_indexSubTableArrayOffset);
+}
+
+void BitmapSizeTable::Builder::SetIndexSubTableArrayOffset(int32_t offset) {
+  InternalWriteData()->WriteULong(
+      EblcTable::Offset::kBitmapSizeTable_indexSubTableArrayOffset, offset);
+}
+
+int32_t BitmapSizeTable::Builder::IndexTableSize() {
+  return InternalReadData()->ReadULongAsInt(
+      EblcTable::Offset::kBitmapSizeTable_indexTableSize);
+}
+
+void BitmapSizeTable::Builder::SetIndexTableSize(int32_t size) {
+  InternalWriteData()->WriteULong(
+      EblcTable::Offset::kBitmapSizeTable_indexTableSize, size);
+}
+
+int32_t BitmapSizeTable::Builder::NumberOfIndexSubTables() {
+  return GetIndexSubTableBuilders()->size();
+}
+
+int32_t BitmapSizeTable::Builder::ColorRef() {
+  return InternalReadData()->ReadULongAsInt(
+      EblcTable::Offset::kBitmapSizeTable_colorRef);
+}
+
+int32_t BitmapSizeTable::Builder::StartGlyphIndex() {
+  return InternalReadData()->ReadUShort(
+      EblcTable::Offset::kBitmapSizeTable_startGlyphIndex);
+}
+
+int32_t BitmapSizeTable::Builder::EndGlyphIndex() {
+  return InternalReadData()->ReadUShort(
+      EblcTable::Offset::kBitmapSizeTable_endGlyphIndex);
+}
+
+int32_t BitmapSizeTable::Builder::PpemX() {
+  return InternalReadData()->ReadByte(
+      EblcTable::Offset::kBitmapSizeTable_ppemX);
+}
+
+int32_t BitmapSizeTable::Builder::PpemY() {
+  return InternalReadData()->ReadByte(
+      EblcTable::Offset::kBitmapSizeTable_ppemY);
+}
+
+int32_t BitmapSizeTable::Builder::BitDepth() {
+  return InternalReadData()->ReadByte(
+      EblcTable::Offset::kBitmapSizeTable_bitDepth);
+}
+
+int32_t BitmapSizeTable::Builder::FlagsAsInt() {
+  return InternalReadData()->ReadChar(
+      EblcTable::Offset::kBitmapSizeTable_flags);
+}
+
+IndexSubTable::Builder* BitmapSizeTable::Builder::IndexSubTableBuilder(
+    int32_t index) {
+  IndexSubTableBuilderList* sub_table_list = GetIndexSubTableBuilders();
+  return sub_table_list->at(index);
+}
+
+CALLER_ATTACH BitmapGlyphInfo* BitmapSizeTable::Builder::GlyphInfo(
+    int32_t glyph_id) {
+  IndexSubTable::Builder* sub_table = SearchIndexSubTables(glyph_id);
+  if (sub_table == NULL) {
+    return NULL;
+  }
+  return sub_table->GlyphInfo(glyph_id);
+}
+
+int32_t BitmapSizeTable::Builder::GlyphOffset(int32_t glyph_id) {
+  IndexSubTable::Builder* subtable = SearchIndexSubTables(glyph_id);
+  if (subtable == NULL) {
+    return -1;
+  }
+  return subtable->GlyphOffset(glyph_id);
+}
+
+int32_t BitmapSizeTable::Builder::GlyphLength(int32_t glyph_id) {
+  IndexSubTable::Builder* subtable = SearchIndexSubTables(glyph_id);
+  if (subtable == NULL) {
+    return -1;
+  }
+  return subtable->GlyphLength(glyph_id);
+}
+
+int32_t BitmapSizeTable::Builder::GlyphFormat(int32_t glyph_id) {
+  IndexSubTable::Builder* subtable = SearchIndexSubTables(glyph_id);
+  if (subtable == NULL) {
+    return -1;
+  }
+  return subtable->image_format();
+}
+
+IndexSubTableBuilderList* BitmapSizeTable::Builder::IndexSubTableBuilders() {
+  return GetIndexSubTableBuilders();
+}
+
+CALLER_ATTACH BitmapSizeTable::Builder::BitmapGlyphInfoIterator*
+BitmapSizeTable::Builder::GetIterator() {
+  Ptr<BitmapSizeTable::Builder::BitmapGlyphInfoIterator> output =
+      new BitmapSizeTable::Builder::BitmapGlyphInfoIterator(this);
+  return output.Detach();
+}
+
+void BitmapSizeTable::Builder::GenerateLocaMap(BitmapGlyphInfoMap* output) {
+  assert(output);
+  Ptr<BitmapSizeTable::Builder::BitmapGlyphInfoIterator> it;
+  it.Attach(GetIterator());
+  while (it->HasNext()) {
+    BitmapGlyphInfoPtr info;
+    info.Attach(it->Next());
+    (*output)[info->glyph_id()] = info;
+  }
+}
+
+void BitmapSizeTable::Builder::Revert() {
+  index_sub_tables_.clear();
+  set_model_changed(false);
+}
+
+BitmapSizeTable::Builder::Builder(WritableFontData* data,
+                                  ReadableFontData* master_data)
+    : SubTable::Builder(data, master_data) {
+}
+
+BitmapSizeTable::Builder::Builder(ReadableFontData* data,
+                                  ReadableFontData* master_data)
+    : SubTable::Builder(data, master_data) {
+}
+
+void BitmapSizeTable::Builder::SetNumberOfIndexSubTables(int32_t count) {
+  InternalWriteData()->WriteULong(
+      EblcTable::Offset::kBitmapSizeTable_numberOfIndexSubTables, count);
+}
+
+IndexSubTable::Builder* BitmapSizeTable::Builder::SearchIndexSubTables(
+    int32_t glyph_id) {
+  // would be faster to binary search but too many size tables don't have
+  // sorted subtables
+#if (SFNTLY_BITMAPSIZE_USE_BINARY_SEARCH)
+  return BinarySearchIndexSubTables(glyph_id);
+#else
+  return LinearSearchIndexSubTables(glyph_id);
+#endif
+}
+
+IndexSubTable::Builder* BitmapSizeTable::Builder::LinearSearchIndexSubTables(
+    int32_t glyph_id) {
+  IndexSubTableBuilderList* subtable_list = GetIndexSubTableBuilders();
+  for (IndexSubTableBuilderList::iterator b = subtable_list->begin(),
+                                          e = subtable_list->end();
+                                          b != e; b++) {
+    if ((*b)->first_glyph_index() <= glyph_id &&
+        (*b)->last_glyph_index() >= glyph_id) {
+      return *b;
+    }
+  }
+  return NULL;
+}
+
+IndexSubTable::Builder* BitmapSizeTable::Builder::BinarySearchIndexSubTables(
+    int32_t glyph_id) {
+  IndexSubTableBuilderList* subtable_list = GetIndexSubTableBuilders();
+  int32_t index = 0;
+  int32_t bottom = 0;
+  int32_t top = subtable_list->size();
+  while (top != bottom) {
+    index = (top + bottom) / 2;
+    IndexSubTable::Builder* subtable = subtable_list->at(index);
+    if (glyph_id < subtable->first_glyph_index()) {
+      // Location beow current location
+      top = index;
+    } else {
+      if (glyph_id <= subtable->last_glyph_index()) {
+        return subtable;
+      } else {
+        bottom = index + 1;
+      }
+    }
+  }
+  return NULL;
+}
+
+IndexSubTableBuilderList* BitmapSizeTable::Builder::GetIndexSubTableBuilders() {
+  if (index_sub_tables_.empty()) {
+    Initialize(InternalReadData());
+    set_model_changed();
+  }
+  return &index_sub_tables_;
+}
+
+void BitmapSizeTable::Builder::Initialize(ReadableFontData* data) {
+  index_sub_tables_.clear();
+  if (data) {
+    int32_t number_of_index_subtables =
+        BitmapSizeTable::NumberOfIndexSubTables(data, 0);
+    index_sub_tables_.resize(number_of_index_subtables);
+    for (int32_t i = 0; i < number_of_index_subtables; ++i) {
+      index_sub_tables_[i].Attach(CreateIndexSubTableBuilder(i));
+    }
+  }
+}
+
+CALLER_ATTACH IndexSubTable::Builder*
+BitmapSizeTable::Builder::CreateIndexSubTableBuilder(int32_t index) {
+  return IndexSubTable::Builder::CreateBuilder(master_read_data(),
+                                               IndexSubTableArrayOffset(),
+                                               index);
+}
+
+/******************************************************************************
+ * BitmapSizeTable::Builder::BitmapGlyphInfoIterator class
+ ******************************************************************************/
+BitmapSizeTable::Builder::BitmapGlyphInfoIterator::BitmapGlyphInfoIterator(
+    BitmapSizeTable::Builder* container)
+    : RefIterator<BitmapGlyphInfo, BitmapSizeTable::Builder>(container) {
+  sub_table_iter_ = container->IndexSubTableBuilders()->begin();
+  sub_table_glyph_info_iter_.Attach((*sub_table_iter_)->GetIterator());
+}
+
+bool BitmapSizeTable::Builder::BitmapGlyphInfoIterator::HasNext() {
+  if (sub_table_glyph_info_iter_ && HasNext(sub_table_glyph_info_iter_)) {
+    return true;
+  }
+  while (++sub_table_iter_ != container()->IndexSubTableBuilders()->end()) {
+    sub_table_glyph_info_iter_.Attach((*sub_table_iter_)->GetIterator());
+    if (HasNext(sub_table_glyph_info_iter_)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+CALLER_ATTACH
+BitmapGlyphInfo* BitmapSizeTable::Builder::BitmapGlyphInfoIterator::Next() {
+  if (!HasNext()) {
+    // Note: In C++, we do not throw exception when there's no element.
+    return NULL;
+  }
+  return Next(sub_table_glyph_info_iter_);
+}
+
+bool BitmapSizeTable::Builder::BitmapGlyphInfoIterator::HasNext(
+    BitmapGlyphInfoIter* iterator_base) {
+  if (iterator_base) {
+    switch (iterator_base->container_base()->index_format()) {
+      case 1: {
+        IndexSubTableFormat1::Builder::BitmapGlyphInfoIterator* it =
+            down_cast<IndexSubTableFormat1::Builder::BitmapGlyphInfoIterator*>(
+                iterator_base);
+        return it->HasNext();
+      }
+
+      case 2: {
+        IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator* it =
+            down_cast<IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator*>(
+                iterator_base);
+        return it->HasNext();
+      }
+
+      case 3: {
+        IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator* it =
+            down_cast<IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator*>(
+                iterator_base);
+        return it->HasNext();
+      }
+
+      case 4: {
+        IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator* it =
+            down_cast<IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator*>(
+                iterator_base);
+        return it->HasNext();
+      }
+
+      case 5: {
+        IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator* it =
+            down_cast<IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator*>(
+                iterator_base);
+        return it->HasNext();
+      }
+
+      default:
+        break;
+    }
+  }
+  return false;
+}
+
+CALLER_ATTACH
+BitmapGlyphInfo* BitmapSizeTable::Builder::BitmapGlyphInfoIterator::Next(
+    BitmapGlyphInfoIter* iterator_base) {
+  if (iterator_base) {
+    switch (iterator_base->container_base()->index_format()) {
+      case 1: {
+        IndexSubTableFormat1::Builder::BitmapGlyphInfoIterator* it =
+            down_cast<IndexSubTableFormat1::Builder::BitmapGlyphInfoIterator*>(
+                iterator_base);
+        return it->Next();
+      }
+
+      case 2: {
+        IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator* it =
+            down_cast<IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator*>(
+                iterator_base);
+        return it->Next();
+      }
+
+      case 3: {
+        IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator* it =
+            down_cast<IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator*>(
+                iterator_base);
+        return it->Next();
+      }
+
+      case 4: {
+        IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator* it =
+            down_cast<IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator*>(
+                iterator_base);
+        return it->Next();
+      }
+
+      case 5: {
+        IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator* it =
+            down_cast<IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator*>(
+                iterator_base);
+        return it->Next();
+      }
+
+      default:
+        break;
+    }
+  }
+  return NULL;
+}
+
+}  // namespace sfntly
diff --git a/sfntly/table/bitmap/bitmap_size_table.h b/sfntly/table/bitmap/bitmap_size_table.h
new file mode 100644
index 0000000..6733e20
--- /dev/null
+++ b/sfntly/table/bitmap/bitmap_size_table.h
@@ -0,0 +1,173 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_BITMAP_SIZE_TABLE_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_BITMAP_SIZE_TABLE_H_
+
+#include "sfntly/port/lock.h"
+#include "sfntly/table/bitmap/bitmap_glyph_info.h"
+#include "sfntly/table/bitmap/index_sub_table.h"
+
+namespace sfntly {
+// Binary search would be faster but many fonts have index subtables that
+// aren't sorted.
+// Note: preprocessor define is used to avoid const expression warnings in C++
+//       code.
+#define SFNTLY_BITMAPSIZE_USE_BINARY_SEARCH 0
+
+class BitmapSizeTable : public SubTable,
+                        public RefCounted<BitmapSizeTable> {
+ public:
+  class Builder : public SubTable::Builder,
+                  public RefCounted<Builder> {
+   public:
+    class BitmapGlyphInfoIterator :
+        public RefIterator<BitmapGlyphInfo, Builder> {
+     public:
+      explicit BitmapGlyphInfoIterator(Builder* container);
+      virtual ~BitmapGlyphInfoIterator() {}
+
+      virtual bool HasNext();
+      CALLER_ATTACH virtual BitmapGlyphInfo* Next();
+
+     private:
+      bool HasNext(BitmapGlyphInfoIter* iterator_base);
+      CALLER_ATTACH BitmapGlyphInfo* Next(BitmapGlyphInfoIter* iterator_base);
+
+      IndexSubTableBuilderList::iterator sub_table_iter_;
+      BitmapGlyphInfoIterPtr sub_table_glyph_info_iter_;
+    };
+
+    virtual ~Builder();
+
+    virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+    virtual void SubDataSet();
+    virtual int32_t SubDataSizeToSerialize();
+    virtual bool SubReadyToSerialize();
+    virtual int32_t SubSerialize(WritableFontData* new_data);
+
+    static CALLER_ATTACH Builder* CreateBuilder(WritableFontData* data,
+                                                ReadableFontData* master_data);
+    static CALLER_ATTACH Builder* CreateBuilder(ReadableFontData* data,
+                                                ReadableFontData* master_data);
+    // Gets the subtable array offset as set in the original table as read from
+    // the font file. This value cannot be explicitly set and will be generated
+    // during table building.
+    // @return the subtable array offset
+    int32_t IndexSubTableArrayOffset();
+
+    // Sets the subtable array offset. This is used only during the building
+    // process when the objects are being serialized.
+    // @param offset the offset to the index subtable array
+    void SetIndexSubTableArrayOffset(int32_t offset);
+
+    // Gets the subtable array size as set in the original table as read from
+    // the font file. This value cannot be explicitly set and will be generated
+    // during table building.
+    // @return the subtable array size
+    int32_t IndexTableSize();
+
+    // Sets the subtable size. This is used only during the building process
+    // when the objects are being serialized.
+    // @param size the offset to the index subtable array
+    void SetIndexTableSize(int32_t size);
+
+    int32_t NumberOfIndexSubTables();
+    int32_t ColorRef();
+    // TODO(stuartg): SBitLineMetrics hori();
+    // TODO(stuartg): SBitLineMetrics vert();
+    int32_t StartGlyphIndex();
+    int32_t EndGlyphIndex();
+    int32_t PpemX();
+    int32_t PpemY();
+    int32_t BitDepth();
+    int32_t FlagsAsInt();
+
+    IndexSubTable::Builder* IndexSubTableBuilder(int32_t index);
+    CALLER_ATTACH BitmapGlyphInfo* GlyphInfo(int32_t glyph_id);
+    int32_t GlyphOffset(int32_t glyph_id);
+    int32_t GlyphLength(int32_t glyph_id);
+    int32_t GlyphFormat(int32_t glyph_id);
+    IndexSubTableBuilderList* IndexSubTableBuilders();
+    // Note: renamed from iterator(), type is the derived type.
+    CALLER_ATTACH BitmapGlyphInfoIterator* GetIterator();
+    void GenerateLocaMap(BitmapGlyphInfoMap* output);
+
+   protected:
+    void Revert();
+
+   private:
+    Builder(WritableFontData* data, ReadableFontData* master_data);
+    Builder(ReadableFontData* data, ReadableFontData* master_data);
+
+    void SetNumberOfIndexSubTables(int32_t count);
+    IndexSubTable::Builder* SearchIndexSubTables(int32_t glyph_id);
+    IndexSubTable::Builder* LinearSearchIndexSubTables(int32_t glyph_id);
+    IndexSubTable::Builder* BinarySearchIndexSubTables(int32_t glyph_id);
+    IndexSubTableBuilderList* GetIndexSubTableBuilders();
+    void Initialize(ReadableFontData* data);
+    CALLER_ATTACH IndexSubTable::Builder* CreateIndexSubTableBuilder(
+        int32_t index);
+
+    IndexSubTableBuilderList index_sub_tables_;
+  };
+
+  virtual ~BitmapSizeTable();
+
+  int32_t IndexSubTableArrayOffset();
+  int32_t IndexTableSize();
+  int32_t NumberOfIndexSubTables();
+  int32_t ColorRef();
+  // TODO(stuartg): SBitLineMetrics hori();
+  // TODO(stuartg): SBitLineMetrics vert();
+  int32_t StartGlyphIndex();
+  int32_t EndGlyphIndex();
+  int32_t PpemX();
+  int32_t PpemY();
+  int32_t BitDepth();
+  int32_t FlagsAsInt();
+
+  // Note: renamed from indexSubTable()
+  IndexSubTable* GetIndexSubTable(int32_t index);
+  int32_t GlyphOffset(int32_t glyph_id);
+  int32_t GlyphLength(int32_t glyph_id);
+  CALLER_ATTACH BitmapGlyphInfo* GlyphInfo(int32_t glyph_id);
+  int32_t GlyphFormat(int32_t glyph_id);
+
+ protected:
+  BitmapSizeTable(ReadableFontData* data,
+                  ReadableFontData* master_data);
+
+ private:
+  static int32_t NumberOfIndexSubTables(ReadableFontData* data,
+                                        int32_t table_offset);
+  IndexSubTable* SearchIndexSubTables(int32_t glyph_id);
+  IndexSubTable* LinearSearchIndexSubTables(int32_t glyph_id);
+  IndexSubTable* BinarySearchIndexSubTables(int32_t glyph_id);
+  CALLER_ATTACH IndexSubTable* CreateIndexSubTable(int32_t index);
+  IndexSubTableList* GetIndexSubTableList();
+
+  Lock index_subtables_lock_;
+  IndexSubTableList index_subtables_;
+};
+typedef Ptr<BitmapSizeTable> BitmapSizeTablePtr;
+typedef std::vector<BitmapSizeTablePtr> BitmapSizeTableList;
+typedef Ptr<BitmapSizeTable::Builder> BitmapSizeTableBuilderPtr;
+typedef std::vector<BitmapSizeTableBuilderPtr> BitmapSizeTableBuilderList;
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_BITMAP_SIZE_TABLE_H_
diff --git a/sfntly/table/bitmap/composite_bitmap_glyph.cc b/sfntly/table/bitmap/composite_bitmap_glyph.cc
new file mode 100644
index 0000000..ae7dc5a
--- /dev/null
+++ b/sfntly/table/bitmap/composite_bitmap_glyph.cc
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/table/bitmap/composite_bitmap_glyph.h"
+
+namespace sfntly {
+/******************************************************************************
+ * CompositeBitmapGlyph class
+ ******************************************************************************/
+CompositeBitmapGlyph::CompositeBitmapGlyph(ReadableFontData* data,
+                                           int32_t format)
+    : BitmapGlyph(data, format) {
+  Initialize(format);
+}
+
+CompositeBitmapGlyph::~CompositeBitmapGlyph() {
+}
+
+int32_t CompositeBitmapGlyph::NumComponents() {
+  return data_->ReadUShort(num_components_offset_);
+}
+
+CompositeBitmapGlyph::Component CompositeBitmapGlyph::GetComponent(
+    int32_t component_num) const {
+  int32_t component_offset = component_array_offset_ +
+                             component_num * Offset::kEbdtComponentLength;
+  return CompositeBitmapGlyph::Component(
+      data_->ReadUShort(component_offset + Offset::kEbdtComponent_glyphCode),
+      data_->ReadChar(component_offset + Offset::kEbdtComponent_xOffset),
+      data_->ReadChar(component_offset + Offset::kEbdtComponent_yOffset));
+}
+
+void CompositeBitmapGlyph::Initialize(int32_t format) {
+  if (format == 8) {
+    num_components_offset_ = Offset::kGlyphFormat8_numComponents;
+    component_array_offset_ = Offset::kGlyphFormat8_componentArray;
+  } else if (format == 9) {
+    num_components_offset_ = Offset::kGlyphFormat9_numComponents;
+    component_array_offset_ = Offset::kGlyphFormat9_componentArray;
+  } else {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IllegalStateException("Attempt to create a Composite Bitmap Glyph "
+                                "with a non-composite format.");
+#endif
+  }
+}
+
+/******************************************************************************
+ * CompositeBitmapGlyph::Component class
+ ******************************************************************************/
+CompositeBitmapGlyph::Component::Component(const Component& rhs)
+    : glyph_code_(rhs.glyph_code_),
+      x_offset_(rhs.x_offset_),
+      y_offset_(rhs.y_offset_) {
+}
+
+bool CompositeBitmapGlyph::Component::operator==(
+    const CompositeBitmapGlyph::Component& rhs) {
+  return glyph_code_ == rhs.glyph_code_;
+}
+
+CompositeBitmapGlyph::Component& CompositeBitmapGlyph::Component::operator=(
+    const CompositeBitmapGlyph::Component& rhs) {
+  glyph_code_ = rhs.glyph_code_;
+  x_offset_ = rhs.x_offset_;
+  y_offset_ = rhs.y_offset_;
+  return *this;
+}
+
+CompositeBitmapGlyph::Component::Component(int32_t glyph_code,
+                                           int32_t x_offset,
+                                           int32_t y_offset)
+    : glyph_code_(glyph_code), x_offset_(x_offset), y_offset_(y_offset) {
+}
+
+/******************************************************************************
+ * CompositeBitmapGlyph::Builder class
+ ******************************************************************************/
+CompositeBitmapGlyph::Builder::Builder(ReadableFontData* data, int32_t format)
+    : BitmapGlyph::Builder(data, format) {
+}
+
+CompositeBitmapGlyph::Builder::Builder(WritableFontData* data, int32_t format)
+    : BitmapGlyph::Builder(data, format) {
+}
+
+CompositeBitmapGlyph::Builder::~Builder() {
+}
+
+CALLER_ATTACH FontDataTable*
+CompositeBitmapGlyph::Builder::SubBuildTable(ReadableFontData* data) {
+  Ptr<CompositeBitmapGlyph> glyph = new CompositeBitmapGlyph(data, format());
+  return glyph.Detach();
+}
+
+}  // namespace sfntly
diff --git a/sfntly/table/bitmap/composite_bitmap_glyph.h b/sfntly/table/bitmap/composite_bitmap_glyph.h
new file mode 100644
index 0000000..897db7e
--- /dev/null
+++ b/sfntly/table/bitmap/composite_bitmap_glyph.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_COMPOSITE_BITMAP_GLYPH_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_COMPOSITE_BITMAP_GLYPH_H_
+
+#include "sfntly/table/bitmap/bitmap_glyph.h"
+
+namespace sfntly {
+
+class CompositeBitmapGlyph : public BitmapGlyph,
+                             public RefCounted<CompositeBitmapGlyph> {
+ public:
+  class Component {
+   public:
+    Component(const Component& rhs);
+
+    int32_t glyph_code() { return glyph_code_; }
+    int32_t x_offset() { return x_offset_; }
+    int32_t y_offset() { return y_offset_; }
+
+    // UNIMPLEMENTED: int hashCode()
+    bool operator==(const Component& rhs);
+    Component& operator=(const Component& rhs);
+
+   protected:
+    Component(int32_t glyph_code, int32_t x_offset, int32_t y_offset);
+
+   private:
+    int32_t glyph_code_;
+    int32_t x_offset_;
+    int32_t y_offset_;
+
+    friend class CompositeBitmapGlyph;
+  };
+
+  class Builder : public BitmapGlyph::Builder,
+                  public RefCounted<Builder> {
+   public:
+    Builder(WritableFontData* data, int32_t format);
+    Builder(ReadableFontData* data, int32_t format);
+    virtual ~Builder();
+
+    virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+  };
+
+  CompositeBitmapGlyph(ReadableFontData* data, int32_t format);
+  virtual ~CompositeBitmapGlyph();
+  int32_t NumComponents();
+  // Note: returned immutable object over stack.
+  Component GetComponent(int32_t component_num) const;
+
+ private:
+  void Initialize(int32_t format);
+
+  int32_t num_components_offset_;
+  int32_t component_array_offset_;
+};
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_COMPOSITE_BITMAP_GLYPH_H_
diff --git a/sfntly/table/bitmap/ebdt_table.cc b/sfntly/table/bitmap/ebdt_table.cc
new file mode 100644
index 0000000..eeb1fa0
--- /dev/null
+++ b/sfntly/table/bitmap/ebdt_table.cc
@@ -0,0 +1,236 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/table/bitmap/ebdt_table.h"
+
+#include <stdlib.h>
+
+#include "sfntly/table/bitmap/composite_bitmap_glyph.h"
+#include "sfntly/table/bitmap/simple_bitmap_glyph.h"
+
+namespace sfntly {
+/******************************************************************************
+ * EbdtTable class
+ ******************************************************************************/
+EbdtTable::~EbdtTable() {
+}
+
+int32_t EbdtTable::Version() {
+  return data_->ReadFixed(Offset::kVersion);
+}
+
+CALLER_ATTACH
+BitmapGlyph* EbdtTable::Glyph(int32_t offset, int32_t length, int32_t format) {
+  ReadableFontDataPtr glyph_data;
+  glyph_data.Attach(down_cast<ReadableFontData*>(data_->Slice(offset, length)));
+  return BitmapGlyph::CreateGlyph(glyph_data, format);
+}
+
+EbdtTable::EbdtTable(Header* header, ReadableFontData* data)
+    : SubTableContainerTable(header, data) {
+}
+
+/******************************************************************************
+ * EbdtTable::Builder class
+ ******************************************************************************/
+EbdtTable::Builder::Builder(Header* header, WritableFontData* data)
+  : SubTableContainerTable::Builder(header, data) {
+}
+
+EbdtTable::Builder::Builder(Header* header, ReadableFontData* data)
+  : SubTableContainerTable::Builder(header, data) {
+}
+
+EbdtTable::Builder::~Builder() {
+}
+
+CALLER_ATTACH FontDataTable*
+    EbdtTable::Builder::SubBuildTable(ReadableFontData* data) {
+  FontDataTablePtr table = new EbdtTable(header(), data);
+  return table.Detach();
+}
+
+void EbdtTable::Builder::SubDataSet() {
+  Revert();
+}
+
+int32_t EbdtTable::Builder::SubDataSizeToSerialize() {
+  if (glyph_builders_.empty()) {
+    return 0;
+  }
+  bool fixed = true;
+  int32_t size = Offset::kHeaderLength;
+  for (BitmapGlyphBuilderList::iterator builder_map = glyph_builders_.begin(),
+                                        builder_end = glyph_builders_.end();
+                                        builder_map != builder_end;
+                                        builder_map++) {
+    for (BitmapGlyphBuilderMap::iterator glyph_entry = builder_map->begin(),
+                                         glyph_entry_end = builder_map->end();
+                                         glyph_entry != glyph_entry_end;
+                                         glyph_entry++) {
+      int32_t glyph_size = glyph_entry->second->SubDataSizeToSerialize();
+      size += abs(glyph_size);
+      fixed = (glyph_size <= 0) ? false : fixed;
+    }
+  }
+  return (fixed ? 1 : -1) * size;
+}
+
+bool EbdtTable::Builder::SubReadyToSerialize() {
+  if (glyph_builders_.empty()) {
+    return false;
+  }
+  return true;
+}
+
+int32_t EbdtTable::Builder::SubSerialize(WritableFontData* new_data) {
+  int32_t size = 0;
+  size += new_data->WriteFixed(Offset::kVersion, kVersion);
+  for (BitmapGlyphBuilderList::iterator builder_map = glyph_builders_.begin(),
+                                        builder_end = glyph_builders_.end();
+                                        builder_map != builder_end;
+                                        builder_map++) {
+    for (BitmapGlyphBuilderMap::iterator glyph_entry = builder_map->begin(),
+                                         glyph_entry_end = builder_map->end();
+                                         glyph_entry != glyph_entry_end;
+                                         glyph_entry++) {
+      WritableFontDataPtr slice;
+      slice.Attach(down_cast<WritableFontData*>(new_data->Slice(size)));
+      size += glyph_entry->second->SubSerialize(slice);
+    }
+  }
+  return size;
+}
+
+void EbdtTable::Builder::SetLoca(BitmapLocaList* loca_list) {
+  assert(loca_list);
+  Revert();
+  glyph_loca_.resize(loca_list->size());
+  std::copy(loca_list->begin(), loca_list->end(), glyph_loca_.begin());
+}
+
+void EbdtTable::Builder::GenerateLocaList(BitmapLocaList* output) {
+  assert(output);
+  output->clear();
+
+  if (glyph_builders_.empty()) {
+    if (glyph_loca_.empty()) {
+      return;
+    }
+  }
+
+  int start_offset = Offset::kHeaderLength;
+  for (BitmapGlyphBuilderList::iterator builder_map = glyph_builders_.begin(),
+                                        builder_end = glyph_builders_.end();
+                                        builder_map != builder_end;
+                                        builder_map++) {
+    BitmapGlyphInfoMap new_loca_map;
+    int32_t glyph_offset = 0;
+    for (BitmapGlyphBuilderMap::iterator glyph_entry = builder_map->begin(),
+                                         glyph_end = builder_map->end();
+                                         glyph_entry != glyph_end;
+                                         glyph_entry++) {
+      BitmapGlyphBuilderPtr builder = glyph_entry->second;
+      int32_t size = builder->SubDataSizeToSerialize();
+      BitmapGlyphInfoPtr info = new BitmapGlyphInfo(glyph_entry->first,
+          start_offset + glyph_offset, size, builder->format());
+      new_loca_map[glyph_entry->first] = info;
+      glyph_offset += size;
+    }
+    start_offset += glyph_offset;
+    output->push_back(new_loca_map);
+  }
+}
+
+BitmapGlyphBuilderList* EbdtTable::Builder::GlyphBuilders() {
+  return GetGlyphBuilders();
+}
+
+void EbdtTable::Builder::SetGlyphBuilders(
+    BitmapGlyphBuilderList* glyph_builders) {
+  glyph_builders_.clear();
+  std::copy(glyph_builders->begin(), glyph_builders->end(),
+            glyph_builders_.begin());
+  set_model_changed();
+}
+
+void EbdtTable::Builder::Revert() {
+  glyph_loca_.clear();
+  glyph_builders_.clear();
+  set_model_changed(false);
+}
+
+CALLER_ATTACH
+EbdtTable::Builder* EbdtTable::Builder::CreateBuilder(Header* header,
+                                                      WritableFontData* data) {
+  Ptr<EbdtTable::Builder> builder;
+  builder = new Builder(header, data);
+  return builder.Detach();
+}
+
+CALLER_ATTACH
+EbdtTable::Builder* EbdtTable::Builder::CreateBuilder(Header* header,
+                                                      ReadableFontData* data) {
+  Ptr<EbdtTable::Builder> builder;
+  builder = new Builder(header, data);
+  return builder.Detach();
+}
+
+BitmapGlyphBuilderList* EbdtTable::Builder::GetGlyphBuilders() {
+  if (glyph_builders_.empty()) {
+    if (glyph_loca_.empty()) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+      throw IllegalStateException(
+          "Loca values not set - unable to parse glyph data.");
+#endif
+      return NULL;
+    }
+    Initialize(InternalReadData(), &glyph_loca_, &glyph_builders_);
+    set_model_changed();
+  }
+  return &glyph_builders_;
+}
+
+void EbdtTable::Builder::Initialize(ReadableFontData* data,
+                                    BitmapLocaList* loca_list,
+                                    BitmapGlyphBuilderList* output) {
+  assert(loca_list);
+  assert(output);
+
+  output->clear();
+  if (data) {
+    for (BitmapLocaList::iterator loca_map = loca_list->begin(),
+                                  loca_end = loca_list->end();
+                                  loca_map != loca_end; loca_map++) {
+      BitmapGlyphBuilderMap glyph_builder_map;
+      for (BitmapGlyphInfoMap::iterator entry = loca_map->begin(),
+                                        entry_end = loca_map->end();
+                                        entry != entry_end; entry++) {
+        BitmapGlyphInfoPtr info = entry->second;
+        ReadableFontDataPtr slice;
+        slice.Attach(down_cast<ReadableFontData*>(data->Slice(
+            info->offset(), info->length())));
+        BitmapGlyphBuilderPtr glyph_builder;
+        glyph_builder.Attach(BitmapGlyph::Builder::CreateGlyphBuilder(
+            slice, info->format()));
+        glyph_builder_map[entry->first] = glyph_builder;
+      }
+      output->push_back(glyph_builder_map);
+    }
+  }
+}
+
+}  // namespace sfntly
diff --git a/sfntly/table/bitmap/ebdt_table.h b/sfntly/table/bitmap/ebdt_table.h
new file mode 100644
index 0000000..d138c14
--- /dev/null
+++ b/sfntly/table/bitmap/ebdt_table.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_EBDT_TABLE_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_EBDT_TABLE_H_
+
+#include "sfntly/table/bitmap/bitmap_glyph.h"
+#include "sfntly/table/bitmap/bitmap_glyph_info.h"
+#include "sfntly/table/subtable_container_table.h"
+
+namespace sfntly {
+
+class EbdtTable : public SubTableContainerTable,
+                  public RefCounted<EbdtTable> {
+ public:
+  struct Offset {
+    enum {
+      kVersion = 0,
+      kHeaderLength = DataSize::kFixed,
+    };
+  };
+
+  class Builder : public SubTableContainerTable::Builder,
+                  public RefCounted<Builder> {
+   public:
+    // Constructor scope altered to public because C++ does not allow base
+    // class to instantiate derived class with protected constructors.
+    Builder(Header* header, WritableFontData* data);
+    Builder(Header* header, ReadableFontData* data);
+    virtual ~Builder();
+
+    virtual int32_t SubSerialize(WritableFontData* new_data);
+    virtual bool SubReadyToSerialize();
+    virtual int32_t SubDataSizeToSerialize();
+    virtual void SubDataSet();
+    virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+
+    void SetLoca(BitmapLocaList* loca_list);
+    void GenerateLocaList(BitmapLocaList* output);
+
+    // Gets the List of glyph builders for the glyph table builder. These may be
+    // manipulated in any way by the caller and the changes will be reflected in
+    // the final glyph table produced.
+    // If there is no current data for the glyph builder or the glyph builders
+    // have not been previously set then this will return an empty glyph builder
+    // List. If there is current data (i.e. data read from an existing font) and
+    // the loca list has not been set or is null, empty, or invalid, then an
+    // empty glyph builder List will be returned.
+    // @return the list of glyph builders
+    BitmapGlyphBuilderList* GlyphBuilders();
+
+    // Replace the internal glyph builders with the one provided. The provided
+    // list and all contained objects belong to this builder.
+    // This call is only required if the entire set of glyphs in the glyph
+    // table builder are being replaced. If the glyph builder list provided from
+    // the {@link EbdtTable.Builder#glyphBuilders()} is being used and modified
+    // then those changes will already be reflected in the glyph table builder.
+    // @param glyphBuilders the new glyph builders
+    void SetGlyphBuilders(BitmapGlyphBuilderList* glyph_builders);
+
+    void Revert();
+
+    // Create a new builder using the header information and data provided.
+    // @param header the header information
+    // @param data the data holding the table
+    static CALLER_ATTACH Builder* CreateBuilder(Header* header,
+                                                WritableFontData* data);
+    static CALLER_ATTACH Builder* CreateBuilder(Header* header,
+                                                ReadableFontData* data);
+
+   private:
+    BitmapGlyphBuilderList* GetGlyphBuilders();
+    static void Initialize(ReadableFontData* data,
+                           BitmapLocaList* loca_list,
+                           BitmapGlyphBuilderList* output);
+
+    static const int32_t kVersion = 0x00020000;  // TODO(stuartg): const/enum
+    BitmapLocaList glyph_loca_;
+    BitmapGlyphBuilderList glyph_builders_;
+  };
+
+  virtual ~EbdtTable();
+  int32_t Version();
+  CALLER_ATTACH BitmapGlyph* Glyph(int32_t offset,
+                                   int32_t length,
+                                   int32_t format);
+ protected:
+  EbdtTable(Header* header, ReadableFontData* data);
+};
+typedef Ptr<EbdtTable> EbdtTablePtr;
+typedef Ptr<EbdtTable::Builder> EbdtTableBuilderPtr;
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_EBDT_TABLE_H_
diff --git a/sfntly/table/bitmap/eblc_table.cc b/sfntly/table/bitmap/eblc_table.cc
new file mode 100644
index 0000000..0ad2764
--- /dev/null
+++ b/sfntly/table/bitmap/eblc_table.cc
@@ -0,0 +1,313 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/table/bitmap/eblc_table.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "sfntly/math/font_math.h"
+
+namespace sfntly {
+/******************************************************************************
+ * EblcTable class
+ ******************************************************************************/
+int32_t EblcTable::Version() {
+  return data_->ReadFixed(Offset::kVersion);
+}
+
+int32_t EblcTable::NumSizes() {
+  return data_->ReadULongAsInt(Offset::kNumSizes);
+}
+
+BitmapSizeTable* EblcTable::GetBitmapSizeTable(int32_t index) {
+  if (index < 0 || index > NumSizes()) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IndexOutOfBoundException(
+        "Size table index is outside the range of tables.");
+#endif
+    return NULL;
+  }
+  BitmapSizeTableList* bitmap_size_table_list = GetBitmapSizeTableList();
+  if (bitmap_size_table_list) {
+    return (*bitmap_size_table_list)[index];
+  }
+  return NULL;
+}
+
+EblcTable::EblcTable(Header* header, ReadableFontData* data)
+    : SubTableContainerTable(header, data) {
+}
+
+BitmapSizeTableList* EblcTable::GetBitmapSizeTableList() {
+  AutoLock lock(bitmap_size_table_lock_);
+  if (bitmap_size_table_.empty()) {
+    CreateBitmapSizeTable(data_, NumSizes(), &bitmap_size_table_);
+  }
+  return &bitmap_size_table_;
+}
+
+// static
+void EblcTable::CreateBitmapSizeTable(ReadableFontData* data,
+                                      int32_t num_sizes,
+                                      BitmapSizeTableList* output) {
+  assert(data);
+  assert(output);
+  for (int32_t i = 0; i < num_sizes; ++i) {
+    ReadableFontDataPtr new_data;
+    new_data.Attach(down_cast<ReadableFontData*>(
+        data->Slice(Offset::kBitmapSizeTableArrayStart +
+                    i * Offset::kBitmapSizeTableLength,
+                    Offset::kBitmapSizeTableLength)));
+    BitmapSizeTableBuilderPtr size_builder;
+    size_builder.Attach(
+        BitmapSizeTable::Builder::CreateBuilder(new_data, data));
+    BitmapSizeTablePtr size;
+    size.Attach(down_cast<BitmapSizeTable*>(size_builder->Build()));
+    output->push_back(size);
+  }
+}
+
+/******************************************************************************
+ * EblcTable::Builder class
+ ******************************************************************************/
+EblcTable::Builder::Builder(Header* header, WritableFontData* data)
+    : SubTableContainerTable::Builder(header, data) {
+}
+
+EblcTable::Builder::Builder(Header* header, ReadableFontData* data)
+    : SubTableContainerTable::Builder(header, data) {
+}
+
+EblcTable::Builder::~Builder() {
+}
+
+int32_t EblcTable::Builder::SubSerialize(WritableFontData* new_data) {
+  // header
+  int32_t size = new_data->WriteFixed(0, kVersion);
+  size += new_data->WriteULong(size, size_table_builders_.size());
+
+  // calculate the offsets
+  // offset to the start of the size table array
+  int32_t size_table_start_offset = size;
+  // walking offset in the size table array
+  int32_t size_table_offset = size_table_start_offset;
+  // offset to the start of the whole index subtable block
+  int32_t sub_table_block_start_offset = size_table_offset +
+      size_table_builders_.size() * Offset::kBitmapSizeTableLength;
+  // walking offset in the index subtable
+  // points to the start of the current subtable block
+  int32_t current_sub_table_block_start_offset = sub_table_block_start_offset;
+
+#if defined (SFNTLY_DEBUG_BITMAP)
+  int32_t size_index = 0;
+#endif
+  for (BitmapSizeTableBuilderList::iterator
+           size_builder = size_table_builders_.begin(),
+           size_builder_end = size_table_builders_.end();
+       size_builder != size_builder_end; size_builder++) {
+    (*size_builder)->SetIndexSubTableArrayOffset(
+        current_sub_table_block_start_offset);
+    IndexSubTableBuilderList* index_sub_table_builder_list =
+        (*size_builder)->IndexSubTableBuilders();
+
+    // walking offset within the current subTable array
+    int32_t index_sub_table_array_offset = current_sub_table_block_start_offset;
+    // walking offset within the subTable entries
+    int32_t index_sub_table_offset = index_sub_table_array_offset +
+        index_sub_table_builder_list->size() * Offset::kIndexSubHeaderLength;
+
+#if defined (SFNTLY_DEBUG_BITMAP)
+    fprintf(stderr, "size %d: sizeTable=%x, current subTable Block=%x, ",
+            size_index, size_table_offset,
+            current_sub_table_block_start_offset);
+    fprintf(stderr, "index subTableStart=%x\n", index_sub_table_offset);
+    size_index++;
+    int32_t sub_table_index = 0;
+#endif
+    for (IndexSubTableBuilderList::iterator
+             index_sub_table_builder = index_sub_table_builder_list->begin(),
+             index_sub_table_builder_end = index_sub_table_builder_list->end();
+         index_sub_table_builder != index_sub_table_builder_end;
+         index_sub_table_builder++) {
+#if defined (SFNTLY_DEBUG_BITMAP)
+      fprintf(stderr, "\tsubTableIndex %d: format=%x, ", sub_table_index,
+              (*index_sub_table_builder)->index_format());
+      fprintf(stderr, "indexSubTableArrayOffset=%x, indexSubTableOffset=%x\n",
+              index_sub_table_array_offset, index_sub_table_offset);
+      sub_table_index++;
+#endif
+      // array entry
+      index_sub_table_array_offset += new_data->WriteUShort(
+          index_sub_table_array_offset,
+          (*index_sub_table_builder)->first_glyph_index());
+      index_sub_table_array_offset += new_data->WriteUShort(
+          index_sub_table_array_offset,
+          (*index_sub_table_builder)->last_glyph_index());
+      index_sub_table_array_offset += new_data->WriteULong(
+          index_sub_table_array_offset,
+          index_sub_table_offset - current_sub_table_block_start_offset);
+
+      // index sub table
+      WritableFontDataPtr slice_index_sub_table;
+      slice_index_sub_table.Attach(down_cast<WritableFontData*>(
+          new_data->Slice(index_sub_table_offset)));
+      int32_t current_sub_table_size =
+          (*index_sub_table_builder)->SubSerialize(slice_index_sub_table);
+      int32_t padding = FontMath::PaddingRequired(current_sub_table_size,
+                                                  DataSize::kULONG);
+#if defined (SFNTLY_DEBUG_BITMAP)
+      fprintf(stderr, "\t\tsubTableSize = %x, padding = %x\n",
+              current_sub_table_size, padding);
+#endif
+      index_sub_table_offset += current_sub_table_size;
+      index_sub_table_offset +=
+          new_data->WritePadding(index_sub_table_offset, padding);
+    }
+
+    // serialize size table
+    (*size_builder)->SetIndexTableSize(
+        index_sub_table_offset - current_sub_table_block_start_offset);
+    WritableFontDataPtr slice_size_table;
+    slice_size_table.Attach(down_cast<WritableFontData*>(
+        new_data->Slice(size_table_offset)));
+    size_table_offset += (*size_builder)->SubSerialize(slice_size_table);
+
+    current_sub_table_block_start_offset = index_sub_table_offset;
+  }
+  return size + current_sub_table_block_start_offset;
+}
+
+bool EblcTable::Builder::SubReadyToSerialize() {
+  if (size_table_builders_.empty()) {
+    return false;
+  }
+  for (BitmapSizeTableBuilderList::iterator b = size_table_builders_.begin(),
+                                            e = size_table_builders_.end();
+                                            b != e; b++) {
+    if (!(*b)->SubReadyToSerialize()) {
+      return false;
+    }
+  }
+  return true;
+}
+
+int32_t EblcTable::Builder::SubDataSizeToSerialize() {
+  if (size_table_builders_.empty()) {
+    return 0;
+  }
+  int32_t size = Offset::kHeaderLength;
+  bool variable = false;
+#if defined (SFNTLY_DEBUG_BITMAP)
+  size_t size_index = 0;
+#endif
+  for (BitmapSizeTableBuilderList::iterator b = size_table_builders_.begin(),
+                                            e = size_table_builders_.end();
+                                            b != e; b++) {
+    int32_t size_builder_size = (*b)->SubDataSizeToSerialize();
+#if defined (SFNTLY_DEBUG_BITMAP)
+    fprintf(stderr, "sizeIndex = %d, sizeBuilderSize=0x%x (%d)\n",
+            size_index++, size_builder_size, size_builder_size);
+#endif
+    variable = size_builder_size > 0 ? variable : true;
+    size += abs(size_builder_size);
+  }
+#if defined (SFNTLY_DEBUG_BITMAP)
+  fprintf(stderr, "eblc size=%d\n", size);
+#endif
+  return variable ? -size : size;
+}
+
+void EblcTable::Builder::SubDataSet() {
+  Revert();
+}
+
+BitmapSizeTableBuilderList* EblcTable::Builder::BitmapSizeBuilders() {
+  return GetSizeList();
+}
+
+void EblcTable::Builder::Revert() {
+  size_table_builders_.clear();
+  set_model_changed(false);
+}
+
+void EblcTable::Builder::GenerateLocaList(BitmapLocaList* output) {
+  assert(output);
+  BitmapSizeTableBuilderList* size_builder_list = GetSizeList();
+  output->clear();
+#if defined (SFNTLY_DEBUG_BITMAP)
+  int32_t size_index = 0;
+#endif
+  for (BitmapSizeTableBuilderList::iterator b = size_builder_list->begin(),
+                                            e = size_builder_list->end();
+                                            b != e; b++) {
+#if defined (SFNTLY_DEBUG_BITMAP)
+    fprintf(stderr, "size table = %d\n", size_index++);
+#endif
+    BitmapGlyphInfoMap loca_map;
+    (*b)->GenerateLocaMap(&loca_map);
+    output->push_back(loca_map);
+  }
+}
+
+CALLER_ATTACH
+FontDataTable* EblcTable::Builder::SubBuildTable(ReadableFontData* data) {
+  Ptr<EblcTable> new_table = new EblcTable(header(), data);
+  return new_table.Detach();
+}
+
+// static
+CALLER_ATTACH EblcTable::Builder*
+    EblcTable::Builder::CreateBuilder(Header* header, WritableFontData* data) {
+  Ptr<EblcTable::Builder> new_builder = new EblcTable::Builder(header, data);
+  return new_builder.Detach();
+}
+
+// static
+CALLER_ATTACH EblcTable::Builder*
+    EblcTable::Builder::CreateBuilder(Header* header, ReadableFontData* data) {
+  Ptr<EblcTable::Builder> new_builder = new EblcTable::Builder(header, data);
+  return new_builder.Detach();
+}
+
+BitmapSizeTableBuilderList* EblcTable::Builder::GetSizeList() {
+  if (size_table_builders_.empty()) {
+    Initialize(InternalReadData(), &size_table_builders_);
+    set_model_changed();
+  }
+  return &size_table_builders_;
+}
+
+void EblcTable::Builder::Initialize(ReadableFontData* data,
+                                    BitmapSizeTableBuilderList* output) {
+  assert(output);
+  if (data) {
+    int32_t num_sizes = data->ReadULongAsInt(Offset::kNumSizes);
+    for (int32_t i = 0; i < num_sizes; ++i) {
+      ReadableFontDataPtr new_data;
+      new_data.Attach(down_cast<ReadableFontData*>(
+          data->Slice(Offset::kBitmapSizeTableArrayStart +
+                      i * Offset::kBitmapSizeTableLength,
+                      Offset::kBitmapSizeTableLength)));
+      BitmapSizeTableBuilderPtr size_builder;
+      size_builder.Attach(BitmapSizeTable::Builder::CreateBuilder(
+          new_data, data));
+      output->push_back(size_builder);
+    }
+  }
+}
+
+}  // namespace sfntly
diff --git a/sfntly/table/bitmap/eblc_table.h b/sfntly/table/bitmap/eblc_table.h
new file mode 100644
index 0000000..b04338a
--- /dev/null
+++ b/sfntly/table/bitmap/eblc_table.h
@@ -0,0 +1,194 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_EBLC_TABLE_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_EBLC_TABLE_H_
+
+#include "sfntly/port/lock.h"
+#include "sfntly/table/bitmap/big_glyph_metrics.h"
+#include "sfntly/table/bitmap/bitmap_glyph.h"
+#include "sfntly/table/bitmap/bitmap_size_table.h"
+#include "sfntly/table/subtable_container_table.h"
+
+namespace sfntly {
+
+class EblcTable : public SubTableContainerTable,
+                  public RefCounted<EblcTable> {
+ public:
+  struct Offset {
+    enum {
+      // header
+      kVersion = 0,
+      kNumSizes = 4,
+      kHeaderLength = kNumSizes + DataSize::kULONG,
+
+      // bitmapSizeTable
+      kBitmapSizeTableArrayStart = kHeaderLength,
+      kBitmapSizeTableLength = 48,
+      kBitmapSizeTable_indexSubTableArrayOffset = 0,
+      kBitmapSizeTable_indexTableSize = 4,
+      kBitmapSizeTable_numberOfIndexSubTables = 8,
+      kBitmapSizeTable_colorRef = 12,
+      kBitmapSizeTable_hori = 16,
+      kBitmapSizeTable_vert = 28,
+      kBitmapSizeTable_startGlyphIndex = 40,
+      kBitmapSizeTable_endGlyphIndex = 42,
+      kBitmapSizeTable_ppemX = 44,
+      kBitmapSizeTable_ppemY = 45,
+      kBitmapSizeTable_bitDepth = 46,
+      kBitmapSizeTable_flags = 47,
+
+      // sbitLineMetrics
+      kSbitLineMetricsLength = 12,
+      kSbitLineMetrics_ascender = 0,
+      kSbitLineMetrics_descender = 1,
+      kSbitLineMetrics_widthMax = 2,
+      kSbitLineMetrics_caretSlopeNumerator = 3,
+      kSbitLineMetrics_caretSlopeDenominator = 4,
+      kSbitLineMetrics_caretOffset = 5,
+      kSbitLineMetrics_minOriginSB = 6,
+      kSbitLineMetrics_minAdvanceSB = 7,
+      kSbitLineMetrics_maxBeforeBL = 8,
+      kSbitLineMetrics_minAfterBL = 9,
+      kSbitLineMetrics_pad1 = 10,
+      kSbitLineMetrics_pad2 = 11,
+
+      // indexSubTable
+      kIndexSubTableEntryLength = 8,
+      kIndexSubTableEntry_firstGlyphIndex = 0,
+      kIndexSubTableEntry_lastGlyphIndex = 2,
+      kIndexSubTableEntry_additionalOffsetToIndexSubTable = 4,
+
+      // indexSubHeader
+      kIndexSubHeaderLength = 8,
+      kIndexSubHeader_indexFormat = 0,
+      kIndexSubHeader_imageFormat = 2,
+      kIndexSubHeader_imageDataOffset = 4,
+
+      // indexSubTable - all offset relative to the subtable start
+
+      // indexSubTable1
+      kIndexSubTable1_offsetArray = kIndexSubHeaderLength,
+      kIndexSubTable1_builderDataSize = kIndexSubHeaderLength,
+
+      // kIndexSubTable2
+      kIndexSubTable2Length = kIndexSubHeaderLength +
+                              DataSize::kULONG +
+                              BitmapGlyph::Offset::kBigGlyphMetricsLength,
+      kIndexSubTable2_imageSize = kIndexSubHeaderLength,
+      kIndexSubTable2_bigGlyphMetrics = kIndexSubTable2_imageSize +
+                                        DataSize::kULONG,
+      kIndexSubTable2_builderDataSize = kIndexSubTable2_bigGlyphMetrics +
+                                        BigGlyphMetrics::Offset::kMetricsLength,
+
+      // kIndexSubTable3
+      kIndexSubTable3_offsetArray = kIndexSubHeaderLength,
+      kIndexSubTable3_builderDataSize = kIndexSubTable3_offsetArray,
+
+      // kIndexSubTable4
+      kIndexSubTable4_numGlyphs = kIndexSubHeaderLength,
+      kIndexSubTable4_glyphArray = kIndexSubTable4_numGlyphs +
+                                   DataSize::kULONG,
+      kIndexSubTable4_codeOffsetPairLength = 2 * DataSize::kUSHORT,
+      kIndexSubTable4_codeOffsetPair_glyphCode = 0,
+      kIndexSubTable4_codeOffsetPair_offset = DataSize::kUSHORT,
+      kIndexSubTable4_builderDataSize = kIndexSubTable4_glyphArray,
+
+      // kIndexSubTable5
+      kIndexSubTable5_imageSize = kIndexSubHeaderLength,
+      kIndexSubTable5_bigGlyphMetrics = kIndexSubTable5_imageSize +
+                                        DataSize::kULONG,
+      kIndexSubTable5_numGlyphs = kIndexSubTable5_bigGlyphMetrics +
+                                  BitmapGlyph::Offset::kBigGlyphMetricsLength,
+      kIndexSubTable5_glyphArray = kIndexSubTable5_numGlyphs +
+                                   DataSize::kULONG,
+      kIndexSubTable5_builderDataSize = kIndexSubTable5_glyphArray,
+
+      // codeOffsetPair
+      kCodeOffsetPairLength = 2 * DataSize::kUSHORT,
+      kCodeOffsetPair_glyphCode = 0,
+      kCodeOffsetPair_offset = DataSize::kUSHORT,
+    };
+  };
+
+  class Builder : public SubTableContainerTable::Builder,
+                  public RefCounted<Builder> {
+   public:
+    // Constructor scope altered to public because C++ does not allow base
+    // class to instantiate derived class with protected constructors.
+    Builder(Header* header, WritableFontData* data);
+    Builder(Header* header, ReadableFontData* data);
+    virtual ~Builder();
+
+    virtual int32_t SubSerialize(WritableFontData* new_data);
+    virtual bool SubReadyToSerialize();
+    virtual int32_t SubDataSizeToSerialize();
+    virtual void SubDataSet();
+    virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+
+    BitmapSizeTableBuilderList* BitmapSizeBuilders();
+    void Revert();
+
+    // Generates the loca list for the EBDT table. The list is intended to be
+    // used by the EBDT to allow it to parse the glyph data and generate glyph
+    // objects. After returning from this method the list belongs to the caller.
+    // The list entries are in the same order as the size table builders are at
+    // the time of this call.
+    // @return the list of loca maps with one for each size table builder
+    void GenerateLocaList(BitmapLocaList* output);
+
+    // Create a new builder using the header information and data provided.
+    // @param header the header information
+    // @param data the data holding the table
+    static CALLER_ATTACH Builder* CreateBuilder(Header* header,
+                                                WritableFontData* data);
+    static CALLER_ATTACH Builder* CreateBuilder(Header* header,
+                                                ReadableFontData* data);
+
+   private:
+    BitmapSizeTableBuilderList* GetSizeList();
+    void Initialize(ReadableFontData* data, BitmapSizeTableBuilderList* output);
+
+    static const int32_t kVersion = 0x00020000;
+    BitmapSizeTableBuilderList size_table_builders_;
+  };
+
+  int32_t Version();
+  int32_t NumSizes();
+  // UNIMPLEMENTED: toString()
+
+  BitmapSizeTable* GetBitmapSizeTable(int32_t index);
+
+  static const int32_t NOTDEF = -1;
+
+ protected:
+  EblcTable(Header* header, ReadableFontData* data);
+
+ private:
+  BitmapSizeTableList* GetBitmapSizeTableList();
+
+  static void CreateBitmapSizeTable(ReadableFontData* data,
+                                    int32_t num_sizes,
+                                    BitmapSizeTableList* output);
+
+  Lock bitmap_size_table_lock_;
+  BitmapSizeTableList bitmap_size_table_;
+};
+typedef Ptr<EblcTable> EblcTablePtr;
+typedef Ptr<EblcTable::Builder> EblcTableBuilderPtr;
+}
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_EBLC_TABLE_H_
diff --git a/sfntly/table/bitmap/ebsc_table.cc b/sfntly/table/bitmap/ebsc_table.cc
new file mode 100644
index 0000000..458c2d4
--- /dev/null
+++ b/sfntly/table/bitmap/ebsc_table.cc
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/table/bitmap/ebsc_table.h"
+
+namespace sfntly {
+/******************************************************************************
+ * EbscTable class
+ ******************************************************************************/
+EbscTable::~EbscTable() {
+}
+
+int32_t EbscTable::Version() {
+  return data_->ReadFixed(Offset::kVersion);
+}
+
+int32_t EbscTable::NumSizes() {
+  return data_->ReadULongAsInt(Offset::kNumSizes);
+}
+
+EbscTable::EbscTable(Header* header, ReadableFontData* data)
+    : Table(header, data) {
+}
+
+/******************************************************************************
+ * EbscTable::BitmapScaleTable class
+ ******************************************************************************/
+EbscTable::BitmapScaleTable::~BitmapScaleTable() {
+}
+
+EbscTable::BitmapScaleTable::BitmapScaleTable(ReadableFontData* data)
+    : SubTable(data) {
+}
+
+int32_t EbscTable::BitmapScaleTable::PpemX() {
+  return data_->ReadByte(Offset::kBitmapScaleTable_ppemX);
+}
+
+int32_t EbscTable::BitmapScaleTable::PpemY() {
+  return data_->ReadByte(Offset::kBitmapScaleTable_ppemY);
+}
+
+int32_t EbscTable::BitmapScaleTable::SubstitutePpemX() {
+  return data_->ReadByte(Offset::kBitmapScaleTable_substitutePpemX);
+}
+
+int32_t EbscTable::BitmapScaleTable::SubstitutePpemY() {
+  return data_->ReadByte(Offset::kBitmapScaleTable_substitutePpemY);
+}
+
+/******************************************************************************
+ * EbscTable::Builder class
+ ******************************************************************************/
+EbscTable::Builder::~Builder() {
+}
+
+CALLER_ATTACH EbscTable::Builder* EbscTable::Builder::CreateBuilder(
+    Header* header, WritableFontData* data) {
+  EbscTableBuilderPtr builder = new EbscTable::Builder(header, data);
+  return builder.Detach();
+}
+
+EbscTable::Builder::Builder(Header* header, WritableFontData* data)
+    : Table::Builder(header, data) {
+}
+
+EbscTable::Builder::Builder(Header* header, ReadableFontData* data)
+    : Table::Builder(header, data) {
+}
+
+CALLER_ATTACH
+FontDataTable* EbscTable::Builder::SubBuildTable(ReadableFontData* data) {
+  EbscTablePtr output = new EbscTable(header(), data);
+  return output.Detach();
+}
+
+void EbscTable::Builder::SubDataSet() {
+  // NOP
+}
+
+int32_t EbscTable::Builder::SubDataSizeToSerialize() {
+  return 0;
+}
+
+bool EbscTable::Builder::SubReadyToSerialize() {
+  return false;
+}
+
+int32_t EbscTable::Builder::SubSerialize(WritableFontData* new_data) {
+  UNREFERENCED_PARAMETER(new_data);
+  return 0;
+}
+
+}  // namespace sfntly
diff --git a/sfntly/table/bitmap/ebsc_table.h b/sfntly/table/bitmap/ebsc_table.h
new file mode 100644
index 0000000..b79df38
--- /dev/null
+++ b/sfntly/table/bitmap/ebsc_table.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_EBSC_TABLE_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_EBSC_TABLE_H_
+
+#include "sfntly/table/bitmap/eblc_table.h"
+
+namespace sfntly {
+
+class EbscTable : public Table,
+                  public RefCounted<EbscTable> {
+ public:
+  struct Offset {
+    enum {
+      // header
+      kVersion = 0,
+      kNumSizes = DataSize::kFixed,
+      kHeaderLength = kNumSizes + DataSize::kULONG,
+      kBitmapScaleTableStart = kHeaderLength,
+
+      // bitmapScaleTable
+      kBitmapScaleTable_hori = 0,
+      kBitmapScaleTable_vert = EblcTable::Offset::kSbitLineMetricsLength,
+      kBitmapScaleTable_ppemX = kBitmapScaleTable_vert +
+                                EblcTable::Offset::kSbitLineMetricsLength,
+      kBitmapScaleTable_ppemY = kBitmapScaleTable_ppemX + DataSize::kBYTE,
+      kBitmapScaleTable_substitutePpemX = kBitmapScaleTable_ppemY +
+                                          DataSize::kBYTE,
+      kBitmapScaleTable_substitutePpemY = kBitmapScaleTable_substitutePpemX +
+                                          DataSize::kBYTE,
+      kBitmapScaleTableLength = kBitmapScaleTable_substitutePpemY +
+                                DataSize::kBYTE,
+    };
+  };
+
+  class BitmapScaleTable : public SubTable,
+                           public RefCounted<BitmapScaleTable> {
+   public:
+    virtual ~BitmapScaleTable();
+    int32_t PpemX();
+    int32_t PpemY();
+    int32_t SubstitutePpemX();
+    int32_t SubstitutePpemY();
+
+   protected:
+    // Note: caller to do data->Slice(offset, Offset::kBitmapScaleTableLength)
+    explicit BitmapScaleTable(ReadableFontData* data);
+  };
+
+  // TODO(stuartg): currently the builder just builds from initial data
+  // - need to make fully working but few if any examples to test with
+  class Builder : public Table::Builder,
+                  public RefCounted<Builder> {
+   public:
+    virtual ~Builder();
+
+    static CALLER_ATTACH Builder* CreateBuilder(Header* header,
+                                                WritableFontData* data);
+
+   protected:
+    Builder(Header* header, WritableFontData* data);
+    Builder(Header* header, ReadableFontData* data);
+
+    virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+    virtual void SubDataSet();
+    virtual int32_t SubDataSizeToSerialize();
+    virtual bool SubReadyToSerialize();
+    virtual int32_t SubSerialize(WritableFontData* new_data);
+  };
+
+  virtual ~EbscTable();
+
+  int32_t Version();
+  int32_t NumSizes();
+  // Note: renamed from bitmapScaleTable
+  CALLER_ATTACH BitmapScaleTable* GetBitmapScaleTable(int32_t index);
+
+ private:
+  EbscTable(Header* header, ReadableFontData* data);
+  friend class Builder;
+};
+typedef Ptr<EbscTable> EbscTablePtr;
+typedef Ptr<EbscTable::Builder> EbscTableBuilderPtr;
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_EBSC_TABLE_H_
diff --git a/sfntly/table/bitmap/glyph_metrics.cc b/sfntly/table/bitmap/glyph_metrics.cc
new file mode 100644
index 0000000..e91eb99
--- /dev/null
+++ b/sfntly/table/bitmap/glyph_metrics.cc
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/table/bitmap/glyph_metrics.h"
+
+namespace sfntly {
+
+GlyphMetrics::~GlyphMetrics() {
+}
+
+GlyphMetrics::GlyphMetrics(ReadableFontData* data)
+    : SubTable(data) {
+}
+
+GlyphMetrics::Builder::~Builder() {
+}
+
+GlyphMetrics::Builder::Builder(WritableFontData* data)
+    : SubTable::Builder(data) {
+}
+
+GlyphMetrics::Builder::Builder(ReadableFontData* data)
+    : SubTable::Builder(data) {
+}
+
+}  // namespace sfntly
diff --git a/sfntly/table/bitmap/glyph_metrics.h b/sfntly/table/bitmap/glyph_metrics.h
new file mode 100644
index 0000000..5f16aaa
--- /dev/null
+++ b/sfntly/table/bitmap/glyph_metrics.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_GLYPH_METRICS_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_GLYPH_METRICS_H_
+
+#include "sfntly/table/subtable.h"
+
+namespace sfntly {
+
+class GlyphMetrics : public SubTable {
+ public:
+  virtual ~GlyphMetrics();
+
+ protected:
+  class Builder : public SubTable::Builder {
+   public:
+    virtual ~Builder();
+
+   protected:
+    explicit Builder(WritableFontData* data);
+    explicit Builder(ReadableFontData* data);
+  };
+
+  explicit GlyphMetrics(ReadableFontData* data);
+};
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_GLYPH_METRICS_H_
diff --git a/sfntly/table/bitmap/index_sub_table.cc b/sfntly/table/bitmap/index_sub_table.cc
new file mode 100644
index 0000000..5e29784
--- /dev/null
+++ b/sfntly/table/bitmap/index_sub_table.cc
@@ -0,0 +1,278 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/table/bitmap/index_sub_table.h"
+
+#include "sfntly/table/bitmap/eblc_table.h"
+#include "sfntly/table/bitmap/index_sub_table_format1.h"
+#include "sfntly/table/bitmap/index_sub_table_format2.h"
+#include "sfntly/table/bitmap/index_sub_table_format3.h"
+#include "sfntly/table/bitmap/index_sub_table_format4.h"
+#include "sfntly/table/bitmap/index_sub_table_format5.h"
+
+namespace sfntly {
+/******************************************************************************
+ * IndexSubTable class
+ ******************************************************************************/
+CALLER_ATTACH BitmapGlyphInfo* IndexSubTable::GlyphInfo(int32_t glyph_id) {
+  int32_t loca = CheckGlyphRange(glyph_id);
+  if (loca == -1) {
+    return NULL;
+  }
+  if (GlyphStartOffset(glyph_id) == -1) {
+    return NULL;
+  }
+  BitmapGlyphInfoPtr output = new BitmapGlyphInfo(glyph_id,
+                                                  image_data_offset(),
+                                                  GlyphStartOffset(glyph_id),
+                                                  GlyphLength(glyph_id),
+                                                  image_format());
+  return output.Detach();
+}
+
+int32_t IndexSubTable::GlyphOffset(int32_t glyph_id) {
+  int32_t glyph_start_offset = GlyphStartOffset(glyph_id);
+  if (glyph_start_offset == -1) {
+    return -1;
+  }
+  return image_data_offset() + glyph_start_offset;
+}
+
+// static
+CALLER_ATTACH IndexSubTable*
+    IndexSubTable::CreateIndexSubTable(ReadableFontData* data,
+                                       int32_t offset_to_index_sub_table_array,
+                                       int32_t array_index) {
+  IndexSubTableBuilderPtr builder;
+  builder.Attach(IndexSubTable::Builder::CreateBuilder(
+      data, offset_to_index_sub_table_array, array_index));
+  return down_cast<IndexSubTable*>(builder->Build());
+}
+
+IndexSubTable::IndexSubTable(ReadableFontData* data,
+                             int32_t first_glyph_index,
+                             int32_t last_glyph_index)
+    : SubTable(data),
+      first_glyph_index_(first_glyph_index),
+      last_glyph_index_(last_glyph_index) {
+  index_format_ =
+      data_->ReadUShort(EblcTable::Offset::kIndexSubHeader_indexFormat);
+  image_format_ =
+      data_->ReadUShort(EblcTable::Offset::kIndexSubHeader_imageFormat);
+  image_data_offset_ =
+      data_->ReadULongAsInt(EblcTable::Offset::kIndexSubHeader_imageDataOffset);
+}
+
+int32_t IndexSubTable::CheckGlyphRange(int32_t glyph_id) {
+  return CheckGlyphRange(glyph_id, first_glyph_index(), last_glyph_index());
+}
+
+// static
+int32_t IndexSubTable::CheckGlyphRange(int32_t glyph_id,
+                                       int32_t first_glyph_id,
+                                       int32_t last_glyph_id) {
+  if (glyph_id < first_glyph_id || glyph_id > last_glyph_id) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IndexOutOfBoundException("Glyph ID is outside of the allowed range.");
+#endif
+    return -1;
+  }
+  return glyph_id - first_glyph_id;
+}
+
+/******************************************************************************
+ * IndexSubTable::Builder class
+ ******************************************************************************/
+IndexSubTable::Builder::~Builder() {
+}
+
+void IndexSubTable::Builder::Revert() {
+  set_model_changed(false);
+  Initialize(InternalReadData());
+}
+
+CALLER_ATTACH BitmapGlyphInfo* IndexSubTable::Builder::GlyphInfo(
+    int32_t glyph_id) {
+  BitmapGlyphInfoPtr glyph_info =
+      new BitmapGlyphInfo(glyph_id,
+                          image_data_offset(),
+                          GlyphStartOffset(glyph_id),
+                          GlyphLength(glyph_id),
+                          image_format());
+  return glyph_info.Detach();
+}
+
+int32_t IndexSubTable::Builder::GlyphOffset(int32_t glyph_id) {
+  return image_data_offset() + GlyphStartOffset(glyph_id);
+}
+
+// static
+CALLER_ATTACH IndexSubTable::Builder*
+IndexSubTable::Builder::CreateBuilder(int32_t index_format) {
+  switch (index_format) {
+    case Format::FORMAT_1:
+      return IndexSubTableFormat1::Builder::CreateBuilder();
+    case Format::FORMAT_2:
+      return IndexSubTableFormat2::Builder::CreateBuilder();
+    case Format::FORMAT_3:
+      return IndexSubTableFormat3::Builder::CreateBuilder();
+    case Format::FORMAT_4:
+      return IndexSubTableFormat4::Builder::CreateBuilder();
+    case Format::FORMAT_5:
+      return IndexSubTableFormat5::Builder::CreateBuilder();
+    default:
+#if !defined (SFNTLY_NO_EXCEPTION)
+      throw IllegalArgumentException("Invalid index subtable format");
+#endif
+      return NULL;
+  }
+}
+
+// static
+CALLER_ATTACH IndexSubTable::Builder*
+IndexSubTable::Builder::CreateBuilder(ReadableFontData* data,
+    int32_t offset_to_index_sub_table_array, int32_t array_index) {
+  int32_t index_sub_table_entry_offset =
+      offset_to_index_sub_table_array +
+      array_index * EblcTable::Offset::kIndexSubTableEntryLength;
+  int32_t first_glyph_index =
+      data->ReadUShort(index_sub_table_entry_offset +
+                       EblcTable::Offset::kIndexSubTableEntry_firstGlyphIndex);
+  int32_t last_glyph_index =
+      data->ReadUShort(index_sub_table_entry_offset +
+                       EblcTable::Offset::kIndexSubTableEntry_lastGlyphIndex);
+  int32_t additional_offset_to_index_subtable = data->ReadULongAsInt(
+      index_sub_table_entry_offset +
+      EblcTable::Offset::kIndexSubTableEntry_additionalOffsetToIndexSubTable);
+  int32_t index_sub_table_offset = offset_to_index_sub_table_array +
+                                   additional_offset_to_index_subtable;
+  int32_t index_format = data->ReadUShort(index_sub_table_offset);
+  switch (index_format) {
+    case 1:
+      return IndexSubTableFormat1::Builder::CreateBuilder(
+          data, index_sub_table_offset, first_glyph_index, last_glyph_index);
+    case 2:
+      return IndexSubTableFormat2::Builder::CreateBuilder(
+          data, index_sub_table_offset, first_glyph_index, last_glyph_index);
+    case 3:
+      return IndexSubTableFormat3::Builder::CreateBuilder(
+          data, index_sub_table_offset, first_glyph_index, last_glyph_index);
+    case 4:
+      return IndexSubTableFormat4::Builder::CreateBuilder(
+          data, index_sub_table_offset, first_glyph_index, last_glyph_index);
+    case 5:
+      return IndexSubTableFormat5::Builder::CreateBuilder(
+          data, index_sub_table_offset, first_glyph_index, last_glyph_index);
+    default:
+      // Unknown format and unable to process.
+#if !defined (SFNTLY_NO_EXCEPTION)
+      throw IllegalArgumentException("Invalid Index Subtable Format");
+#endif
+      break;
+  }
+  return NULL;
+}
+
+CALLER_ATTACH
+FontDataTable* IndexSubTable::Builder::SubBuildTable(ReadableFontData* data) {
+  UNREFERENCED_PARAMETER(data);
+  return NULL;
+}
+
+void IndexSubTable::Builder::SubDataSet() {
+  // NOP
+}
+
+int32_t IndexSubTable::Builder::SubDataSizeToSerialize() {
+  return 0;
+}
+
+bool IndexSubTable::Builder::SubReadyToSerialize() {
+  return false;
+}
+
+int32_t IndexSubTable::Builder::SubSerialize(WritableFontData* new_data) {
+  UNREFERENCED_PARAMETER(new_data);
+  return 0;
+}
+
+IndexSubTable::Builder::Builder(int32_t data_size, int32_t index_format)
+    : SubTable::Builder(data_size),
+      first_glyph_index_(0),
+      last_glyph_index_(0),
+      index_format_(index_format),
+      image_format_(0),
+      image_data_offset_(0) {
+}
+
+IndexSubTable::Builder::Builder(int32_t index_format,
+                                int32_t image_format,
+                                int32_t image_data_offset,
+                                int32_t data_size)
+    : SubTable::Builder(data_size),
+      first_glyph_index_(0),
+      last_glyph_index_(0),
+      index_format_(index_format),
+      image_format_(image_format),
+      image_data_offset_(image_data_offset) {
+}
+
+IndexSubTable::Builder::Builder(WritableFontData* data,
+                                int32_t first_glyph_index,
+                                int32_t last_glyph_index)
+    : SubTable::Builder(data),
+      first_glyph_index_(first_glyph_index),
+      last_glyph_index_(last_glyph_index) {
+  Initialize(data);
+}
+
+IndexSubTable::Builder::Builder(ReadableFontData* data,
+                                int32_t first_glyph_index,
+                                int32_t last_glyph_index)
+    : SubTable::Builder(data),
+      first_glyph_index_(first_glyph_index),
+      last_glyph_index_(last_glyph_index) {
+  Initialize(data);
+}
+
+int32_t IndexSubTable::Builder::CheckGlyphRange(int32_t glyph_id) {
+  return IndexSubTable::CheckGlyphRange(glyph_id,
+                                        first_glyph_index(),
+                                        last_glyph_index());
+}
+
+int32_t IndexSubTable::Builder::SerializeIndexSubHeader(
+    WritableFontData* data) {
+  int32_t size =
+      data->WriteUShort(EblcTable::Offset::kIndexSubHeader_indexFormat,
+                        index_format());
+  size += data->WriteUShort(EblcTable::Offset::kIndexSubHeader_imageFormat,
+                            image_format());
+  size += data->WriteULong(EblcTable::Offset::kIndexSubHeader_imageDataOffset,
+                           image_data_offset());
+  return size;
+}
+
+void IndexSubTable::Builder::Initialize(ReadableFontData* data) {
+  index_format_ =
+      data->ReadUShort(EblcTable::Offset::kIndexSubHeader_indexFormat);
+  image_format_ =
+      data->ReadUShort(EblcTable::Offset::kIndexSubHeader_imageFormat);
+  image_data_offset_ =
+      data->ReadULongAsInt(EblcTable::Offset::kIndexSubHeader_imageDataOffset);
+}
+
+}  // namespace sfntly
diff --git a/sfntly/table/bitmap/index_sub_table.h b/sfntly/table/bitmap/index_sub_table.h
new file mode 100644
index 0000000..6d27129
--- /dev/null
+++ b/sfntly/table/bitmap/index_sub_table.h
@@ -0,0 +1,178 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_H_
+
+#include <vector>
+
+#include "sfntly/port/java_iterator.h"
+#include "sfntly/table/subtable.h"
+#include "sfntly/table/bitmap/bitmap_glyph_info.h"
+
+namespace sfntly {
+
+class IndexSubTable : public SubTable {
+ public:
+  struct Format {
+    enum {
+      FORMAT_1 = 1,
+      FORMAT_2 = 2,
+      FORMAT_3 = 3,
+      FORMAT_4 = 4,
+      FORMAT_5 = 5,
+    };
+  };
+
+  class Builder : public SubTable::Builder {
+   public:
+    virtual ~Builder();
+
+    void Revert();
+
+    int32_t index_format() { return index_format_; }
+    int32_t first_glyph_index() { return first_glyph_index_; }
+    void set_first_glyph_index(int32_t v) { first_glyph_index_ = v; }
+    int32_t last_glyph_index() { return last_glyph_index_; }
+    void set_last_glyph_index(int32_t v) { last_glyph_index_ = v; }
+    int32_t image_format() { return image_format_; }
+    void set_image_format(int32_t v) { image_format_ = v; }
+    int32_t image_data_offset() { return image_data_offset_; }
+    void set_image_data_offset(int32_t v) { image_data_offset_ = v; }
+
+    virtual int32_t NumGlyphs() = 0;
+
+    // Gets the glyph info for the specified glyph id.
+    // @param glyphId the glyph id to look up
+    // @return the glyph info
+    CALLER_ATTACH virtual BitmapGlyphInfo* GlyphInfo(int32_t glyph_id);
+
+    // Gets the full offset of the glyph within the EBDT table.
+    // @param glyphId the glyph id
+    // @return the glyph offset
+    virtual int32_t GlyphOffset(int32_t glyph_id);
+
+    // Gets the offset of the glyph relative to the block for this index
+    // subtable.
+    // @param glyphId the glyph id
+    // @return the glyph offset
+    virtual int32_t GlyphStartOffset(int32_t glyph_id) = 0;
+
+    // Gets the length of the glyph within the EBDT table.
+    // @param glyphId the glyph id
+    // @return the glyph offset
+    virtual int32_t GlyphLength(int32_t glyph_id) = 0;
+
+    // Note: renamed from java iterator()
+    CALLER_ATTACH virtual Iterator<BitmapGlyphInfo, IndexSubTable::Builder>*
+        GetIterator() = 0;
+
+    // Static instantiation function.
+    static CALLER_ATTACH Builder* CreateBuilder(int32_t index_format);
+    static CALLER_ATTACH Builder*
+        CreateBuilder(ReadableFontData* data,
+                      int32_t offset_to_index_sub_table_array,
+                      int32_t array_index);
+
+    // The following methods will never be called but they need to be here to
+    // allow the BitmapSizeTable to see these methods through an abstract
+    // reference.
+    virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+    virtual void SubDataSet();
+    virtual int32_t SubDataSizeToSerialize();
+    virtual bool SubReadyToSerialize();
+    virtual int32_t SubSerialize(WritableFontData* new_data);
+
+   protected:
+    Builder(int32_t data_size, int32_t index_format);
+    Builder(int32_t index_format,
+            int32_t image_format,
+            int32_t image_data_offset,
+            int32_t data_size);
+    Builder(WritableFontData* data,
+            int32_t first_glyph_index,
+            int32_t last_glyph_index);
+    Builder(ReadableFontData* data,
+            int32_t first_glyph_index,
+            int32_t last_glyph_index);
+
+    // Checks that the glyph id is within the correct range. If it returns the
+    // offset of the glyph id from the start of the range.
+    // @param glyphId
+    // @return the offset of the glyphId from the start of the glyph range
+    // @throws IndexOutOfBoundsException if the glyph id is not within the
+    //         correct range
+    int32_t CheckGlyphRange(int32_t glyph_id);
+    int32_t SerializeIndexSubHeader(WritableFontData* data);
+
+   private:
+    void Initialize(ReadableFontData* data);
+
+    int32_t first_glyph_index_;
+    int32_t last_glyph_index_;
+    int32_t index_format_;
+    int32_t image_format_;
+    int32_t image_data_offset_;
+  };
+
+  int32_t index_format() { return index_format_; }
+  int32_t first_glyph_index() { return first_glyph_index_; }
+  int32_t last_glyph_index() { return last_glyph_index_; }
+  int32_t image_format() { return image_format_; }
+  int32_t image_data_offset() { return image_data_offset_; }
+
+  CALLER_ATTACH BitmapGlyphInfo* GlyphInfo(int32_t glyph_id);
+  virtual int32_t GlyphOffset(int32_t glyph_id);
+  virtual int32_t GlyphStartOffset(int32_t glyph_id) = 0;
+  virtual int32_t GlyphLength(int32_t glyph_id) = 0;
+  virtual int32_t NumGlyphs() = 0;
+
+  static CALLER_ATTACH IndexSubTable*
+      CreateIndexSubTable(ReadableFontData* data,
+                          int32_t offset_to_index_sub_table_array,
+                          int32_t array_index);
+
+ protected:
+  // Note: the constructor does not implement offset/length form provided in
+  //       Java to avoid heavy lifting in constructors.  Callers to call
+  //       GetDataLength() static method of the derived class to get proper
+  //       length and slice ahead.
+  IndexSubTable(ReadableFontData* data,
+                int32_t first_glyph_index,
+                int32_t last_glyph_index);
+
+  int32_t CheckGlyphRange(int32_t glyph_id);
+  static int32_t CheckGlyphRange(int32_t glyph_id,
+                                 int32_t first_glyph_id,
+                                 int32_t last_glyph_id);
+
+ private:
+  int32_t first_glyph_index_;
+  int32_t last_glyph_index_;
+  int32_t index_format_;
+  int32_t image_format_;
+  int32_t image_data_offset_;
+};
+typedef Ptr<IndexSubTable> IndexSubTablePtr;
+typedef std::vector<IndexSubTablePtr> IndexSubTableList;
+typedef Ptr<IndexSubTable::Builder> IndexSubTableBuilderPtr;
+typedef std::vector<IndexSubTableBuilderPtr> IndexSubTableBuilderList;
+typedef Iterator<BitmapGlyphInfo, IndexSubTable::Builder> BitmapGlyphInfoIter;
+typedef Ptr<BitmapGlyphInfoIter> BitmapGlyphInfoIterPtr;
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_H_
diff --git a/sfntly/table/bitmap/index_sub_table_format1.cc b/sfntly/table/bitmap/index_sub_table_format1.cc
new file mode 100644
index 0000000..5199e18
--- /dev/null
+++ b/sfntly/table/bitmap/index_sub_table_format1.cc
@@ -0,0 +1,302 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/table/bitmap/index_sub_table_format1.h"
+
+#include "sfntly/table/bitmap/eblc_table.h"
+
+namespace sfntly {
+/******************************************************************************
+ * IndexSubTableFormat1 class
+ ******************************************************************************/
+// static
+int32_t IndexSubTableFormat1::GetDataLength(ReadableFontData* data,
+                                            int32_t offset,
+                                            int32_t first,
+                                            int32_t last) {
+  UNREFERENCED_PARAMETER(data);
+  UNREFERENCED_PARAMETER(offset);
+  return (last - first + 1 + 1) * DataSize::kULONG;
+}
+
+IndexSubTableFormat1::~IndexSubTableFormat1() {
+}
+
+int32_t IndexSubTableFormat1::NumGlyphs() {
+  return last_glyph_index() - first_glyph_index() + 1;
+}
+
+int32_t IndexSubTableFormat1::GlyphStartOffset(int32_t glyph_id) {
+  int32_t loca = CheckGlyphRange(glyph_id);
+  if (loca == -1) {
+    return -1;
+  }
+  return Loca(loca);
+}
+
+int32_t IndexSubTableFormat1::GlyphLength(int32_t glyph_id) {
+  int32_t loca = CheckGlyphRange(glyph_id);
+  if (loca == -1) {
+    return -1;
+  }
+  return Loca(loca + 1) - Loca(loca);
+}
+
+IndexSubTableFormat1::IndexSubTableFormat1(ReadableFontData* data,
+                                           int32_t first_glyph_index,
+                                           int32_t last_glyph_index)
+    : IndexSubTable(data, first_glyph_index, last_glyph_index) {
+}
+
+int32_t IndexSubTableFormat1::Loca(int32_t loca) {
+  return image_data_offset() +
+         data_->ReadULongAsInt(EblcTable::Offset::kIndexSubTable1_offsetArray +
+                               loca * DataSize::kULONG);
+}
+
+/******************************************************************************
+ * IndexSubTableFormat1::Builder class
+ ******************************************************************************/
+IndexSubTableFormat1::Builder::~Builder() {
+}
+
+int32_t IndexSubTableFormat1::Builder::NumGlyphs() {
+  return GetOffsetArray()->size() - 1;
+}
+
+int32_t IndexSubTableFormat1::Builder::GlyphLength(int32_t glyph_id) {
+  int32_t loca = CheckGlyphRange(glyph_id);
+  if (loca == -1) {
+    return 0;
+  }
+  IntegerList* offset_array = GetOffsetArray();
+  return offset_array->at(loca + 1) - offset_array->at(loca);
+}
+
+int32_t IndexSubTableFormat1::Builder::GlyphStartOffset(int32_t glyph_id) {
+  int32_t loca = CheckGlyphRange(glyph_id);
+  if (loca == -1) {
+    return -1;
+  }
+  return GetOffsetArray()->at(loca);
+}
+
+CALLER_ATTACH IndexSubTableFormat1::Builder::BitmapGlyphInfoIterator*
+    IndexSubTableFormat1::Builder::GetIterator() {
+  Ptr<IndexSubTableFormat1::Builder::BitmapGlyphInfoIterator> it =
+      new IndexSubTableFormat1::Builder::BitmapGlyphInfoIterator(this);
+  return it.Detach();
+}
+
+// static
+CALLER_ATTACH IndexSubTableFormat1::Builder*
+IndexSubTableFormat1::Builder::CreateBuilder() {
+  IndexSubTableFormat1BuilderPtr output = new IndexSubTableFormat1::Builder();
+  return output.Detach();
+}
+
+// static
+CALLER_ATTACH IndexSubTableFormat1::Builder*
+IndexSubTableFormat1::Builder::CreateBuilder(ReadableFontData* data,
+                                             int32_t index_sub_table_offset,
+                                             int32_t first_glyph_index,
+                                             int32_t last_glyph_index) {
+  int32_t length = Builder::DataLength(data,
+                                       index_sub_table_offset,
+                                       first_glyph_index,
+                                       last_glyph_index);
+  ReadableFontDataPtr new_data;
+  new_data.Attach(down_cast<ReadableFontData*>(
+      data->Slice(index_sub_table_offset, length)));
+  if (new_data == NULL) {
+    return NULL;
+  }
+  IndexSubTableFormat1BuilderPtr output =
+      new IndexSubTableFormat1::Builder(new_data,
+                                        first_glyph_index,
+                                        last_glyph_index);
+  return output.Detach();
+}
+
+
+// static
+CALLER_ATTACH IndexSubTableFormat1::Builder*
+IndexSubTableFormat1::Builder::CreateBuilder(WritableFontData* data,
+                                             int32_t index_sub_table_offset,
+                                             int32_t first_glyph_index,
+                                             int32_t last_glyph_index) {
+  int32_t length = Builder::DataLength(data,
+                                       index_sub_table_offset,
+                                       first_glyph_index,
+                                       last_glyph_index);
+  WritableFontDataPtr new_data;
+  new_data.Attach(down_cast<WritableFontData*>(
+      data->Slice(index_sub_table_offset, length)));
+  IndexSubTableFormat1BuilderPtr output =
+      new IndexSubTableFormat1::Builder(new_data,
+                                        first_glyph_index,
+                                        last_glyph_index);
+  return output.Detach();
+}
+
+CALLER_ATTACH FontDataTable* IndexSubTableFormat1::Builder::SubBuildTable(
+    ReadableFontData* data) {
+  IndexSubTableFormat1Ptr output = new IndexSubTableFormat1(
+      data, first_glyph_index(), last_glyph_index());
+  return output.Detach();
+}
+
+void IndexSubTableFormat1::Builder::SubDataSet() {
+  Revert();
+}
+
+int32_t IndexSubTableFormat1::Builder::SubDataSizeToSerialize() {
+  if (offset_array_.empty()) {
+    return InternalReadData()->Length();
+  }
+  return EblcTable::Offset::kIndexSubHeaderLength +
+         offset_array_.size() * DataSize::kULONG;
+}
+
+bool IndexSubTableFormat1::Builder::SubReadyToSerialize() {
+  if (!offset_array_.empty()) {
+    return true;
+  }
+  return false;
+}
+
+int32_t IndexSubTableFormat1::Builder::SubSerialize(
+    WritableFontData* new_data) {
+  int32_t size = SerializeIndexSubHeader(new_data);
+  if (!model_changed()) {
+    if (InternalReadData() == NULL) {
+      return size;
+    }
+    ReadableFontDataPtr source;
+    WritableFontDataPtr target;
+    source.Attach(down_cast<ReadableFontData*>(InternalReadData()->Slice(
+        EblcTable::Offset::kIndexSubTable1_offsetArray)));
+    target.Attach(down_cast<WritableFontData*>(new_data->Slice(
+        EblcTable::Offset::kIndexSubTable1_offsetArray)));
+    size += source->CopyTo(target);
+  } else {
+    for (IntegerList::iterator b = GetOffsetArray()->begin(),
+                               e = GetOffsetArray()->end(); b != e; b++) {
+      size += new_data->WriteLong(size, *b);
+    }
+  }
+  return size;
+}
+
+IntegerList* IndexSubTableFormat1::Builder::OffsetArray() {
+  return GetOffsetArray();
+}
+
+void IndexSubTableFormat1::Builder::SetOffsetArray(
+    const IntegerList& offset_array) {
+  offset_array_.clear();
+  offset_array_ = offset_array;
+  set_model_changed();
+}
+
+void IndexSubTableFormat1::Builder::Revert() {
+  offset_array_.clear();
+  IndexSubTable::Builder::Revert();
+}
+
+IndexSubTableFormat1::Builder::Builder()
+    : IndexSubTable::Builder(EblcTable::Offset::kIndexSubTable1_builderDataSize,
+                             IndexSubTable::Format::FORMAT_1) {
+}
+
+IndexSubTableFormat1::Builder::Builder(WritableFontData* data,
+                                       int32_t first_glyph_index,
+                                       int32_t last_glyph_index)
+    : IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
+}
+
+IndexSubTableFormat1::Builder::Builder(ReadableFontData* data,
+                                       int32_t first_glyph_index,
+                                       int32_t last_glyph_index)
+    : IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
+}
+
+IntegerList* IndexSubTableFormat1::Builder::GetOffsetArray() {
+  if (offset_array_.empty()) {
+    Initialize(InternalReadData());
+    set_model_changed();
+  }
+  return &offset_array_;
+}
+
+void IndexSubTableFormat1::Builder::Initialize(ReadableFontData* data) {
+  offset_array_.clear();
+  if (data) {
+    int32_t num_offsets = (last_glyph_index() - first_glyph_index() + 1) + 1;
+    for (int32_t i = 0; i < num_offsets; ++i) {
+      offset_array_.push_back(data->ReadULongAsInt(
+          EblcTable::Offset::kIndexSubTable1_offsetArray +
+          i * DataSize::kULONG));
+    }
+  }
+}
+
+// static
+int32_t IndexSubTableFormat1::Builder::DataLength(
+    ReadableFontData* data,
+    int32_t index_sub_table_offset,
+    int32_t first_glyph_index,
+    int32_t last_glyph_index) {
+  UNREFERENCED_PARAMETER(data);
+  UNREFERENCED_PARAMETER(index_sub_table_offset);
+  return EblcTable::Offset::kIndexSubHeaderLength +
+         (last_glyph_index - first_glyph_index + 1 + 1) * DataSize::kULONG;
+}
+
+/******************************************************************************
+ * IndexSubTableFormat1::Builder::BitmapGlyphInfoIterator class
+ ******************************************************************************/
+IndexSubTableFormat1::Builder::BitmapGlyphInfoIterator::BitmapGlyphInfoIterator(
+    IndexSubTableFormat1::Builder* container)
+    : RefIterator<BitmapGlyphInfo, IndexSubTableFormat1::Builder,
+                  IndexSubTable::Builder>(container) {
+  glyph_id_ = container->first_glyph_index();
+}
+
+bool IndexSubTableFormat1::Builder::BitmapGlyphInfoIterator::HasNext() {
+  if (glyph_id_ <= container()->last_glyph_index()) {
+    return true;
+  }
+  return false;
+}
+
+CALLER_ATTACH BitmapGlyphInfo*
+IndexSubTableFormat1::Builder::BitmapGlyphInfoIterator::Next() {
+  BitmapGlyphInfoPtr output;
+  if (!HasNext()) {
+    // Note: In C++, we do not throw exception when there's no element.
+    return NULL;
+  }
+  output = new BitmapGlyphInfo(glyph_id_,
+                               container()->image_data_offset(),
+                               container()->GlyphStartOffset(glyph_id_),
+                               container()->GlyphLength(glyph_id_),
+                               container()->image_format());
+  glyph_id_++;
+  return output.Detach();
+}
+
+}  // namespace sfntly
diff --git a/sfntly/table/bitmap/index_sub_table_format1.h b/sfntly/table/bitmap/index_sub_table_format1.h
new file mode 100644
index 0000000..33171c1
--- /dev/null
+++ b/sfntly/table/bitmap/index_sub_table_format1.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT1_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT1_H_
+
+#include "sfntly/port/java_iterator.h"
+#include "sfntly/table/bitmap/index_sub_table.h"
+
+namespace sfntly {
+// Format 1 Index Subtable Entry.
+class IndexSubTableFormat1 : public IndexSubTable,
+                             public RefCounted<IndexSubTableFormat1> {
+ public:
+  class Builder : public IndexSubTable::Builder,
+                  public RefCounted<Builder> {
+   public:
+    class BitmapGlyphInfoIterator
+        : public RefIterator<BitmapGlyphInfo, Builder, IndexSubTable::Builder> {
+     public:
+      explicit BitmapGlyphInfoIterator(Builder* container);
+      virtual ~BitmapGlyphInfoIterator() {}
+
+      virtual bool HasNext();
+      CALLER_ATTACH virtual BitmapGlyphInfo* Next();
+
+     private:
+      int32_t glyph_id_;
+    };
+
+    virtual ~Builder();
+    virtual int32_t NumGlyphs();
+    virtual int32_t GlyphLength(int32_t glyph_id);
+    virtual int32_t GlyphStartOffset(int32_t glyph_id);
+    CALLER_ATTACH virtual BitmapGlyphInfoIterator* GetIterator();
+
+    virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+    virtual void SubDataSet();
+    virtual int32_t SubDataSizeToSerialize();
+    virtual bool SubReadyToSerialize();
+    virtual int32_t SubSerialize(WritableFontData* new_data);
+
+    IntegerList* OffsetArray();
+    void SetOffsetArray(const IntegerList& offset_array);
+    CALLER_ATTACH BitmapGlyphInfoIter* Iterator();
+
+    static CALLER_ATTACH Builder* CreateBuilder();
+    static CALLER_ATTACH Builder* CreateBuilder(ReadableFontData* data,
+                                                int32_t index_sub_table_offset,
+                                                int32_t first_glyph_index,
+                                                int32_t last_glyph_index);
+    static CALLER_ATTACH Builder* CreateBuilder(WritableFontData* data,
+                                                int32_t index_sub_table_offset,
+                                                int32_t first_glyph_index,
+                                                int32_t last_glyph_index);
+
+   protected:
+    void Revert();
+
+   private:
+    Builder();
+    Builder(WritableFontData* data,
+            int32_t first_glyph_index,
+            int32_t last_glyph_index);
+    Builder(ReadableFontData* data,
+            int32_t first_glyph_index,
+            int32_t last_glyph_index);
+    IntegerList* GetOffsetArray();
+    void Initialize(ReadableFontData* data);
+
+    static int32_t DataLength(ReadableFontData* data,
+                              int32_t index_sub_table_offset,
+                              int32_t first_glyph_index,
+                              int32_t last_glyph_index);
+
+    IntegerList offset_array_;
+  };
+
+  virtual ~IndexSubTableFormat1();
+
+  virtual int32_t NumGlyphs();
+  virtual int32_t GlyphStartOffset(int32_t glyph_id);
+  virtual int32_t GlyphLength(int32_t glyph_id);
+
+  static int32_t GetDataLength(ReadableFontData* data,
+                               int32_t offset,
+                               int32_t first,
+                               int32_t last);
+
+ private:
+  IndexSubTableFormat1(ReadableFontData* data,
+                       int32_t first_glyph_index,
+                       int32_t last_glyph_index);
+  int32_t Loca(int32_t loca_index);
+
+  friend class Builder;
+};
+typedef Ptr<IndexSubTableFormat1> IndexSubTableFormat1Ptr;
+typedef Ptr<IndexSubTableFormat1::Builder> IndexSubTableFormat1BuilderPtr;
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT1_H_
diff --git a/sfntly/table/bitmap/index_sub_table_format2.cc b/sfntly/table/bitmap/index_sub_table_format2.cc
new file mode 100644
index 0000000..ce73e9b
--- /dev/null
+++ b/sfntly/table/bitmap/index_sub_table_format2.cc
@@ -0,0 +1,275 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/table/bitmap/index_sub_table_format2.h"
+
+#include "sfntly/table/bitmap/eblc_table.h"
+
+namespace sfntly {
+/******************************************************************************
+ * IndexSubTableFormat2 class
+ ******************************************************************************/
+IndexSubTableFormat2::~IndexSubTableFormat2() {
+}
+
+int32_t IndexSubTableFormat2::ImageSize() {
+  return data_->ReadULongAsInt(EblcTable::Offset::kIndexSubTable2_imageSize);
+}
+
+CALLER_ATTACH BigGlyphMetrics* IndexSubTableFormat2::BigMetrics() {
+  ReadableFontDataPtr slice;
+  slice.Attach(down_cast<ReadableFontData*>(
+      data_->Slice(EblcTable::Offset::kIndexSubTable2_bigGlyphMetrics,
+                   BigGlyphMetrics::Offset::kMetricsLength)));
+  BigGlyphMetricsPtr output = new BigGlyphMetrics(slice);
+  return output.Detach();
+}
+
+int32_t IndexSubTableFormat2::NumGlyphs() {
+  return last_glyph_index() - first_glyph_index() + 1;
+}
+
+int32_t IndexSubTableFormat2::GlyphStartOffset(int32_t glyph_id) {
+  int32_t loca = CheckGlyphRange(glyph_id);
+  if (loca == -1) {
+    return -1;
+  }
+  return loca * image_size_;
+}
+
+int32_t IndexSubTableFormat2::GlyphLength(int32_t glyph_id) {
+  if (CheckGlyphRange(glyph_id) == -1) {
+    return 0;
+  }
+  return image_size_;
+}
+
+IndexSubTableFormat2::IndexSubTableFormat2(ReadableFontData* data,
+                                           int32_t first,
+                                           int32_t last)
+    : IndexSubTable(data, first, last) {
+  image_size_ =
+      data_->ReadULongAsInt(EblcTable::Offset::kIndexSubTable2_imageSize);
+}
+
+/******************************************************************************
+ * IndexSubTableFormat2::Builder class
+ ******************************************************************************/
+IndexSubTableFormat2::Builder::~Builder() {
+}
+
+int32_t IndexSubTableFormat2::Builder::NumGlyphs() {
+  return last_glyph_index() - first_glyph_index() + 1;
+}
+
+int32_t IndexSubTableFormat2::Builder::GlyphStartOffset(int32_t glyph_id) {
+  int32_t loca = CheckGlyphRange(glyph_id);
+  if (loca == -1) {
+    return -1;
+  }
+  return loca * ImageSize();
+}
+
+int32_t IndexSubTableFormat2::Builder::GlyphLength(int32_t glyph_id) {
+  int32_t loca = CheckGlyphRange(glyph_id);
+  if (loca == -1) {
+    return 0;
+  }
+  return ImageSize();
+}
+
+CALLER_ATTACH IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator*
+    IndexSubTableFormat2::Builder::GetIterator() {
+  Ptr<IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator> it =
+      new IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator(this);
+  return it.Detach();
+}
+
+int32_t IndexSubTableFormat2::Builder::ImageSize() {
+  return InternalReadData()->ReadULongAsInt(
+      EblcTable::Offset::kIndexSubTable2_imageSize);
+}
+
+void IndexSubTableFormat2::Builder::SetImageSize(int32_t image_size) {
+  InternalWriteData()->WriteULong(EblcTable::Offset::kIndexSubTable2_imageSize,
+                                  image_size);
+}
+
+BigGlyphMetrics::Builder* IndexSubTableFormat2::Builder::BigMetrics() {
+  if (metrics_ == NULL) {
+    WritableFontDataPtr data;
+    data.Attach(down_cast<WritableFontData*>(InternalWriteData()->Slice(
+        EblcTable::Offset::kIndexSubTable2_bigGlyphMetrics,
+        BigGlyphMetrics::Offset::kMetricsLength)));
+    metrics_ = new BigGlyphMetrics::Builder(data);
+  }
+  return metrics_;
+}
+
+// static
+CALLER_ATTACH IndexSubTableFormat2::Builder*
+IndexSubTableFormat2::Builder::CreateBuilder() {
+  IndexSubTableFormat2BuilderPtr output = new IndexSubTableFormat2::Builder();
+  return output.Detach();
+}
+
+// static
+CALLER_ATTACH IndexSubTableFormat2::Builder*
+IndexSubTableFormat2::Builder::CreateBuilder(ReadableFontData* data,
+                                             int32_t index_sub_table_offset,
+                                             int32_t first_glyph_index,
+                                             int32_t last_glyph_index) {
+  int32_t length = Builder::DataLength(data,
+                                       index_sub_table_offset,
+                                       first_glyph_index,
+                                       last_glyph_index);
+  ReadableFontDataPtr new_data;
+  new_data.Attach(down_cast<ReadableFontData*>(
+      data->Slice(index_sub_table_offset, length)));
+  if (new_data == NULL) {
+    return NULL;
+  }
+  IndexSubTableFormat2BuilderPtr output =
+      new IndexSubTableFormat2::Builder(new_data,
+                                        first_glyph_index,
+                                        last_glyph_index);
+  return output.Detach();
+}
+
+// static
+CALLER_ATTACH IndexSubTableFormat2::Builder*
+IndexSubTableFormat2::Builder::CreateBuilder(WritableFontData* data,
+                                             int32_t index_sub_table_offset,
+                                             int32_t first_glyph_index,
+                                             int32_t last_glyph_index) {
+  int32_t length = Builder::DataLength(data,
+                                       index_sub_table_offset,
+                                       first_glyph_index,
+                                       last_glyph_index);
+  WritableFontDataPtr new_data;
+  new_data.Attach(down_cast<WritableFontData*>(
+      data->Slice(index_sub_table_offset, length)));
+  IndexSubTableFormat2BuilderPtr output =
+      new IndexSubTableFormat2::Builder(new_data,
+                                        first_glyph_index,
+                                        last_glyph_index);
+  return output.Detach();
+}
+
+CALLER_ATTACH FontDataTable* IndexSubTableFormat2::Builder::SubBuildTable(
+    ReadableFontData* data) {
+  IndexSubTableFormat2Ptr output = new IndexSubTableFormat2(
+      data, first_glyph_index(), last_glyph_index());
+  return output.Detach();
+}
+
+void IndexSubTableFormat2::Builder::SubDataSet() {
+  Revert();
+}
+
+int32_t IndexSubTableFormat2::Builder::SubDataSizeToSerialize() {
+  return EblcTable::Offset::kIndexSubTable2Length;
+}
+
+bool IndexSubTableFormat2::Builder::SubReadyToSerialize() {
+  return true;
+}
+
+int32_t IndexSubTableFormat2::Builder::SubSerialize(
+    WritableFontData* new_data) {
+  int32_t size = SerializeIndexSubHeader(new_data);
+  if (metrics_ == NULL) {
+    ReadableFontDataPtr source;
+    WritableFontDataPtr target;
+    source.Attach(down_cast<ReadableFontData*>(
+        InternalReadData()->Slice(size)));
+    target.Attach(down_cast<WritableFontData*>(new_data->Slice(size)));
+    size += source->CopyTo(target);
+  } else {
+    WritableFontDataPtr slice;
+    size += new_data->WriteLong(EblcTable::Offset::kIndexSubTable2_imageSize,
+                                ImageSize());
+    slice.Attach(down_cast<WritableFontData*>(new_data->Slice(size)));
+    size += metrics_->SubSerialize(slice);
+  }
+  return size;
+}
+
+IndexSubTableFormat2::Builder::Builder()
+    : IndexSubTable::Builder(EblcTable::Offset::kIndexSubTable3_builderDataSize,
+                             IndexSubTable::Format::FORMAT_2) {
+  metrics_.Attach(BigGlyphMetrics::Builder::CreateBuilder());
+}
+
+IndexSubTableFormat2::Builder::Builder(WritableFontData* data,
+                                       int32_t first_glyph_index,
+                                       int32_t last_glyph_index)
+    : IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
+}
+
+IndexSubTableFormat2::Builder::Builder(ReadableFontData* data,
+                                       int32_t first_glyph_index,
+                                       int32_t last_glyph_index)
+    : IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
+}
+
+// static
+int32_t IndexSubTableFormat2::Builder::DataLength(
+    ReadableFontData* data,
+    int32_t index_sub_table_offset,
+    int32_t first_glyph_index,
+    int32_t last_glyph_index) {
+  UNREFERENCED_PARAMETER(data);
+  UNREFERENCED_PARAMETER(index_sub_table_offset);
+  UNREFERENCED_PARAMETER(first_glyph_index);
+  UNREFERENCED_PARAMETER(last_glyph_index);
+  return EblcTable::Offset::kIndexSubTable2Length;
+}
+
+/******************************************************************************
+ * IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator class
+ ******************************************************************************/
+IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator::BitmapGlyphInfoIterator(
+    IndexSubTableFormat2::Builder* container)
+    : RefIterator<BitmapGlyphInfo, IndexSubTableFormat2::Builder,
+                  IndexSubTable::Builder>(container) {
+  glyph_id_ = container->first_glyph_index();
+}
+
+bool IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator::HasNext() {
+  if (glyph_id_ <= container()->last_glyph_index()) {
+    return true;
+  }
+  return false;
+}
+
+CALLER_ATTACH BitmapGlyphInfo*
+IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator::Next() {
+  BitmapGlyphInfoPtr output;
+  if (!HasNext()) {
+    // Note: In C++, we do not throw exception when there's no element.
+    return NULL;
+  }
+  output = new BitmapGlyphInfo(glyph_id_,
+                               container()->image_data_offset(),
+                               container()->GlyphStartOffset(glyph_id_),
+                               container()->GlyphLength(glyph_id_),
+                               container()->image_format());
+  glyph_id_++;
+  return output.Detach();
+}
+
+}  // namespace sfntly
diff --git a/sfntly/table/bitmap/index_sub_table_format2.h b/sfntly/table/bitmap/index_sub_table_format2.h
new file mode 100644
index 0000000..784e8a3
--- /dev/null
+++ b/sfntly/table/bitmap/index_sub_table_format2.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT2_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT2_H_
+
+#include "sfntly/table/bitmap/index_sub_table.h"
+#include "sfntly/table/bitmap/big_glyph_metrics.h"
+
+namespace sfntly {
+// Format 2 Index Subtable Entry.
+class IndexSubTableFormat2 : public IndexSubTable,
+                             public RefCounted<IndexSubTableFormat2> {
+ public:
+  class Builder : public IndexSubTable::Builder,
+                  public RefCounted<Builder> {
+   public:
+    class BitmapGlyphInfoIterator
+        : public RefIterator<BitmapGlyphInfo, Builder, IndexSubTable::Builder> {
+     public:
+      explicit BitmapGlyphInfoIterator(Builder* container);
+      virtual ~BitmapGlyphInfoIterator() {}
+
+      virtual bool HasNext();
+      CALLER_ATTACH virtual BitmapGlyphInfo* Next();
+
+     private:
+      int32_t glyph_id_;
+    };
+
+    virtual ~Builder();
+    virtual int32_t NumGlyphs();
+    virtual int32_t GlyphStartOffset(int32_t glyph_id);
+    virtual int32_t GlyphLength(int32_t glyph_id);
+    CALLER_ATTACH virtual BitmapGlyphInfoIterator* GetIterator();
+
+    virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+    virtual void SubDataSet();
+    virtual int32_t SubDataSizeToSerialize();
+    virtual bool SubReadyToSerialize();
+    virtual int32_t SubSerialize(WritableFontData* new_data);
+
+    int32_t ImageSize();
+    void SetImageSize(int32_t image_size);
+    BigGlyphMetrics::Builder* BigMetrics();
+
+    static CALLER_ATTACH Builder* CreateBuilder();
+    static CALLER_ATTACH Builder* CreateBuilder(ReadableFontData* data,
+                                                int32_t index_sub_table_offset,
+                                                int32_t first_glyph_index,
+                                                int32_t last_glyph_index);
+    static CALLER_ATTACH Builder* CreateBuilder(WritableFontData* data,
+                                                int32_t index_sub_table_offset,
+                                                int32_t first_glyph_index,
+                                                int32_t last_glyph_index);
+   private:
+    Builder();
+    Builder(WritableFontData* data,
+            int32_t first_glyph_index,
+            int32_t last_glyph_index);
+    Builder(ReadableFontData* data,
+            int32_t first_glyph_index,
+            int32_t last_glyph_index);
+
+    static int32_t DataLength(ReadableFontData* data,
+                              int32_t index_sub_table_offset,
+                              int32_t first_glyph_index,
+                              int32_t last_glyph_index);
+
+    BigGlyphMetricsBuilderPtr metrics_;
+  };
+
+  virtual ~IndexSubTableFormat2();
+
+  int32_t ImageSize();
+  CALLER_ATTACH BigGlyphMetrics* BigMetrics();
+
+  virtual int32_t NumGlyphs();
+  virtual int32_t GlyphStartOffset(int32_t glyph_id);
+  virtual int32_t GlyphLength(int32_t glyph_id);
+
+ private:
+  IndexSubTableFormat2(ReadableFontData* data, int32_t first, int32_t last);
+
+  int32_t image_size_;
+  friend class Builder;
+};
+typedef Ptr<IndexSubTableFormat2> IndexSubTableFormat2Ptr;
+typedef Ptr<IndexSubTableFormat2::Builder> IndexSubTableFormat2BuilderPtr;
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT1_H_
diff --git a/sfntly/table/bitmap/index_sub_table_format3.cc b/sfntly/table/bitmap/index_sub_table_format3.cc
new file mode 100644
index 0000000..e2679b7
--- /dev/null
+++ b/sfntly/table/bitmap/index_sub_table_format3.cc
@@ -0,0 +1,298 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/table/bitmap/index_sub_table_format3.h"
+
+#include "sfntly/table/bitmap/eblc_table.h"
+
+namespace sfntly {
+/******************************************************************************
+ * IndexSubTableFormat3 class
+ ******************************************************************************/
+IndexSubTableFormat3::~IndexSubTableFormat3() {
+}
+
+int32_t IndexSubTableFormat3::NumGlyphs() {
+  return last_glyph_index() - first_glyph_index() + 1;
+}
+
+int32_t IndexSubTableFormat3::GlyphStartOffset(int32_t glyph_id) {
+  int32_t loca = CheckGlyphRange(glyph_id);
+  if (loca != -1) {
+    return Loca(loca);
+  }
+  return -1;
+}
+
+int32_t IndexSubTableFormat3::GlyphLength(int32_t glyph_id) {
+  int32_t loca = CheckGlyphRange(glyph_id);
+  if (loca != -1) {
+    return Loca(glyph_id + 1) - Loca(glyph_id);
+  }
+  return 0;
+}
+
+// static
+int32_t IndexSubTableFormat3::GetDataLength(ReadableFontData* data,
+                                            int32_t offset,
+                                            int32_t first,
+                                            int32_t last) {
+  UNREFERENCED_PARAMETER(data);
+  UNREFERENCED_PARAMETER(offset);
+  return (last - first + 1 + 1) * DataSize::kUSHORT;
+}
+
+IndexSubTableFormat3::IndexSubTableFormat3(ReadableFontData* data,
+                                           int32_t first_glyph_index,
+                                           int32_t last_glyph_index)
+    : IndexSubTable(data, first_glyph_index, last_glyph_index) {
+}
+
+int32_t IndexSubTableFormat3::Loca(int32_t loca) {
+  int32_t read_offset =
+      data_->ReadUShort(EblcTable::Offset::kIndexSubTable3_offsetArray +
+                        loca * DataSize::kUSHORT);
+  return read_offset;
+}
+
+/******************************************************************************
+ * IndexSubTableFormat3::Builder class
+ ******************************************************************************/
+IndexSubTableFormat3::Builder::~Builder() {
+}
+
+int32_t IndexSubTableFormat3::Builder::NumGlyphs() {
+  return GetOffsetArray()->size() - 1;
+}
+
+int32_t IndexSubTableFormat3::Builder::GlyphStartOffset(int32_t glyph_id) {
+  int32_t loca = CheckGlyphRange(glyph_id);
+  if (loca == -1) {
+    return -1;
+  }
+  return GetOffsetArray()->at(loca);
+}
+
+int32_t IndexSubTableFormat3::Builder::GlyphLength(int32_t glyph_id) {
+  int32_t loca = CheckGlyphRange(glyph_id);
+  if (loca == -1) {
+    return 0;
+  }
+  IntegerList* offset_array = GetOffsetArray();
+  return offset_array->at(loca + 1) - offset_array->at(loca);
+}
+
+CALLER_ATTACH IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator*
+    IndexSubTableFormat3::Builder::GetIterator() {
+  Ptr<IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator> it =
+      new IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator(this);
+  return it.Detach();
+}
+
+void IndexSubTableFormat3::Builder::Revert() {
+  offset_array_.clear();
+  IndexSubTable::Builder::Revert();
+}
+
+void IndexSubTableFormat3::Builder::SetOffsetArray(
+    const IntegerList& offset_array) {
+  offset_array_.clear();
+  offset_array_ = offset_array;
+  set_model_changed();
+}
+
+// static
+CALLER_ATTACH IndexSubTableFormat3::Builder*
+IndexSubTableFormat3::Builder::CreateBuilder() {
+  IndexSubTableFormat3BuilderPtr output = new IndexSubTableFormat3::Builder();
+  return output.Detach();
+}
+
+// static
+CALLER_ATTACH IndexSubTableFormat3::Builder*
+IndexSubTableFormat3::Builder::CreateBuilder(ReadableFontData* data,
+                                             int32_t index_sub_table_offset,
+                                             int32_t first_glyph_index,
+                                             int32_t last_glyph_index) {
+  int32_t length = Builder::DataLength(data,
+                                       index_sub_table_offset,
+                                       first_glyph_index,
+                                       last_glyph_index);
+  ReadableFontDataPtr new_data;
+  new_data.Attach(down_cast<ReadableFontData*>(
+      data->Slice(index_sub_table_offset, length)));
+  if (new_data == NULL) {
+    return NULL;
+  }
+  IndexSubTableFormat3BuilderPtr output =
+      new IndexSubTableFormat3::Builder(new_data,
+                                        first_glyph_index,
+                                        last_glyph_index);
+  return output.Detach();
+}
+
+// static
+CALLER_ATTACH IndexSubTableFormat3::Builder*
+IndexSubTableFormat3::Builder::CreateBuilder(WritableFontData* data,
+                                             int32_t index_sub_table_offset,
+                                             int32_t first_glyph_index,
+                                             int32_t last_glyph_index) {
+  int32_t length = Builder::DataLength(data,
+                                       index_sub_table_offset,
+                                       first_glyph_index,
+                                       last_glyph_index);
+  WritableFontDataPtr new_data;
+  new_data.Attach(down_cast<WritableFontData*>(
+      data->Slice(index_sub_table_offset, length)));
+  IndexSubTableFormat3BuilderPtr output =
+      new IndexSubTableFormat3::Builder(new_data,
+                                        first_glyph_index,
+                                        last_glyph_index);
+  return output.Detach();
+}
+
+CALLER_ATTACH FontDataTable* IndexSubTableFormat3::Builder::SubBuildTable(
+    ReadableFontData* data) {
+  IndexSubTableFormat3Ptr output = new IndexSubTableFormat3(
+      data, first_glyph_index(), last_glyph_index());
+  return output.Detach();
+}
+
+void IndexSubTableFormat3::Builder::SubDataSet() {
+  Revert();
+}
+
+int32_t IndexSubTableFormat3::Builder::SubDataSizeToSerialize() {
+  if (offset_array_.empty()) {
+    return InternalReadData()->Length();
+  }
+  return EblcTable::Offset::kIndexSubHeaderLength +
+         offset_array_.size() * DataSize::kULONG;
+}
+
+bool IndexSubTableFormat3::Builder::SubReadyToSerialize() {
+  if (!offset_array_.empty()) {
+    return true;
+  }
+  return false;
+}
+
+int32_t IndexSubTableFormat3::Builder::SubSerialize(
+    WritableFontData* new_data) {
+  int32_t size = SerializeIndexSubHeader(new_data);
+  if (!model_changed()) {
+    if (InternalReadData() == NULL) {
+      return size;
+    }
+    ReadableFontDataPtr source;
+    WritableFontDataPtr target;
+    source.Attach(down_cast<ReadableFontData*>(InternalReadData()->Slice(
+        EblcTable::Offset::kIndexSubTable3_offsetArray)));
+    target.Attach(down_cast<WritableFontData*>(new_data->Slice(
+        EblcTable::Offset::kIndexSubTable3_offsetArray)));
+    size += source->CopyTo(target);
+  } else {
+    for (IntegerList::iterator b = GetOffsetArray()->begin(),
+                               e = GetOffsetArray()->end(); b != e; b++) {
+      size += new_data->WriteUShort(size, *b);
+    }
+  }
+  return size;
+}
+
+IndexSubTableFormat3::Builder::Builder()
+    : IndexSubTable::Builder(EblcTable::Offset::kIndexSubTable3_builderDataSize,
+                             IndexSubTable::Format::FORMAT_3) {
+}
+
+IndexSubTableFormat3::Builder::Builder(WritableFontData* data,
+                                       int32_t first_glyph_index,
+                                       int32_t last_glyph_index)
+    : IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
+}
+
+IndexSubTableFormat3::Builder::Builder(ReadableFontData* data,
+                                       int32_t first_glyph_index,
+                                       int32_t last_glyph_index)
+    : IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
+}
+
+IntegerList* IndexSubTableFormat3::Builder::GetOffsetArray() {
+  if (offset_array_.empty()) {
+    Initialize(InternalReadData());
+    set_model_changed();
+  }
+  return &offset_array_;
+}
+
+void IndexSubTableFormat3::Builder::Initialize(ReadableFontData* data) {
+  offset_array_.clear();
+  if (data) {
+    int32_t num_offsets = (last_glyph_index() - first_glyph_index() + 1) + 1;
+    for (int32_t i = 0; i < num_offsets; ++i) {
+      offset_array_.push_back(data->ReadUShort(
+         EblcTable::Offset::kIndexSubTable3_offsetArray +
+         i * DataSize::kUSHORT));
+    }
+  }
+}
+
+// static
+int32_t IndexSubTableFormat3::Builder::DataLength(
+    ReadableFontData* data,
+    int32_t index_sub_table_offset,
+    int32_t first_glyph_index,
+    int32_t last_glyph_index) {
+  UNREFERENCED_PARAMETER(data);
+  UNREFERENCED_PARAMETER(index_sub_table_offset);
+  return EblcTable::Offset::kIndexSubHeaderLength +
+         (last_glyph_index - first_glyph_index + 1 + 1) * DataSize::kUSHORT;
+}
+
+/******************************************************************************
+ * IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator class
+ ******************************************************************************/
+IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator::BitmapGlyphInfoIterator(
+    IndexSubTableFormat3::Builder* container)
+    : RefIterator<BitmapGlyphInfo, IndexSubTableFormat3::Builder,
+                  IndexSubTable::Builder>(container) {
+  glyph_id_ = container->first_glyph_index();
+}
+
+bool IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator::HasNext() {
+  if (glyph_id_ <= container()->last_glyph_index()) {
+    return true;
+  }
+  return false;
+}
+
+CALLER_ATTACH BitmapGlyphInfo*
+IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator::Next() {
+  BitmapGlyphInfoPtr output;
+  if (!HasNext()) {
+    // Note: In C++, we do not throw exception when there's no element.
+    return NULL;
+  }
+  output = new BitmapGlyphInfo(glyph_id_,
+                               container()->image_data_offset(),
+                               container()->GlyphStartOffset(glyph_id_),
+                               container()->GlyphLength(glyph_id_),
+                               container()->image_format());
+  glyph_id_++;
+  return output.Detach();
+}
+
+}  // namespace sfntly
diff --git a/sfntly/table/bitmap/index_sub_table_format3.h b/sfntly/table/bitmap/index_sub_table_format3.h
new file mode 100644
index 0000000..d71f857
--- /dev/null
+++ b/sfntly/table/bitmap/index_sub_table_format3.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT3_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT3_H_
+
+#include "sfntly/table/bitmap/index_sub_table.h"
+
+namespace sfntly {
+// Format 3 Index Subtable Entry.
+class IndexSubTableFormat3 : public IndexSubTable,
+                             public RefCounted<IndexSubTableFormat3> {
+ public:
+  class Builder : public IndexSubTable::Builder,
+                  public RefCounted<Builder> {
+   public:
+    class BitmapGlyphInfoIterator
+        : public RefIterator<BitmapGlyphInfo, Builder, IndexSubTable::Builder> {
+     public:
+      explicit BitmapGlyphInfoIterator(Builder* container);
+      virtual ~BitmapGlyphInfoIterator() {}
+
+      virtual bool HasNext();
+      CALLER_ATTACH virtual BitmapGlyphInfo* Next();
+
+     private:
+      int32_t glyph_id_;
+    };
+
+    virtual ~Builder();
+    virtual int32_t NumGlyphs();
+    virtual int32_t GlyphStartOffset(int32_t glyph_id);
+    virtual int32_t GlyphLength(int32_t glyph_id);
+    CALLER_ATTACH virtual BitmapGlyphInfoIterator* GetIterator();
+
+    virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+    virtual void SubDataSet();
+    virtual int32_t SubDataSizeToSerialize();
+    virtual bool SubReadyToSerialize();
+    virtual int32_t SubSerialize(WritableFontData* new_data);
+
+    void SetOffsetArray(const IntegerList& offset_array);
+
+    static CALLER_ATTACH Builder* CreateBuilder();
+    static CALLER_ATTACH Builder* CreateBuilder(ReadableFontData* data,
+                                                int32_t index_sub_table_offset,
+                                                int32_t first_glyph_index,
+                                                int32_t last_glyph_index);
+    static CALLER_ATTACH Builder* CreateBuilder(WritableFontData* data,
+                                                int32_t index_sub_table_offset,
+                                                int32_t first_glyph_index,
+                                                int32_t last_glyph_index);
+
+   protected:
+    void Revert();
+
+   private:
+    Builder();
+    Builder(WritableFontData* data,
+            int32_t first_glyph_index,
+            int32_t last_glyph_index);
+    Builder(ReadableFontData* data,
+            int32_t first_glyph_index,
+            int32_t last_glyph_index);
+    IntegerList* GetOffsetArray();
+    void Initialize(ReadableFontData* data);
+
+    static int32_t DataLength(ReadableFontData* data,
+                              int32_t index_sub_table_offset,
+                              int32_t first_glyph_index,
+                              int32_t last_glyph_index);
+
+    IntegerList offset_array_;
+  };
+
+  virtual ~IndexSubTableFormat3();
+
+  virtual int32_t NumGlyphs();
+  virtual int32_t GlyphStartOffset(int32_t glyph_id);
+  virtual int32_t GlyphLength(int32_t glyph_id);
+
+  static int32_t GetDataLength(ReadableFontData* data,
+                               int32_t offset,
+                               int32_t first,
+                               int32_t last);
+
+ private:
+  IndexSubTableFormat3(ReadableFontData* data,
+                       int32_t first_glyph_index,
+                       int32_t last_glyph_index);
+  int32_t Loca(int32_t loca_index);
+
+  friend class Builder;
+};
+typedef Ptr<IndexSubTableFormat3> IndexSubTableFormat3Ptr;
+typedef Ptr<IndexSubTableFormat3::Builder> IndexSubTableFormat3BuilderPtr;
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT3_H_
diff --git a/sfntly/table/bitmap/index_sub_table_format4.cc b/sfntly/table/bitmap/index_sub_table_format4.cc
new file mode 100644
index 0000000..5baa2a5
--- /dev/null
+++ b/sfntly/table/bitmap/index_sub_table_format4.cc
@@ -0,0 +1,384 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/table/bitmap/index_sub_table_format4.h"
+
+#include "sfntly/table/bitmap/eblc_table.h"
+
+namespace sfntly {
+/******************************************************************************
+ * IndexSubTableFormat4 class
+ ******************************************************************************/
+IndexSubTableFormat4::~IndexSubTableFormat4() {
+}
+
+int32_t IndexSubTableFormat4::NumGlyphs() {
+  return IndexSubTableFormat4::NumGlyphs(data_, 0);
+}
+
+int32_t IndexSubTableFormat4::GlyphStartOffset(int32_t glyph_id) {
+  int32_t loca = CheckGlyphRange(glyph_id);
+  if (loca == -1) {
+    return -1;
+  }
+  int32_t pair_index = FindCodeOffsetPair(glyph_id);
+  if (pair_index < 0) {
+    return -1;
+  }
+  return data_->ReadUShort(EblcTable::Offset::kIndexSubTable4_glyphArray +
+                           pair_index *
+                           EblcTable::Offset::kCodeOffsetPairLength +
+                           EblcTable::Offset::kCodeOffsetPair_offset);
+}
+
+int32_t IndexSubTableFormat4::GlyphLength(int32_t glyph_id) {
+  int32_t loca = CheckGlyphRange(glyph_id);
+  if (loca == -1) {
+    return -1;
+  }
+
+  int32_t pair_index = FindCodeOffsetPair(glyph_id);
+  if (pair_index < 0) {
+    return -1;
+  }
+  return data_->ReadUShort(
+             EblcTable::Offset::kIndexSubTable4_glyphArray +
+             (pair_index + 1) * EblcTable::Offset::kCodeOffsetPairLength +
+             EblcTable::Offset::kCodeOffsetPair_offset) -
+         data_->ReadUShort(
+             EblcTable::Offset::kIndexSubTable4_glyphArray +
+             (pair_index) * EblcTable::Offset::kCodeOffsetPairLength +
+             EblcTable::Offset::kCodeOffsetPair_offset);
+}
+
+IndexSubTableFormat4::IndexSubTableFormat4(ReadableFontData* data,
+                                           int32_t first,
+                                           int32_t last)
+    : IndexSubTable(data, first, last) {
+}
+
+int32_t IndexSubTableFormat4::FindCodeOffsetPair(int32_t glyph_id) {
+  return data_->SearchUShort(EblcTable::Offset::kIndexSubTable4_glyphArray,
+                             EblcTable::Offset::kCodeOffsetPairLength,
+                             NumGlyphs(),
+                             glyph_id);
+}
+
+int32_t IndexSubTableFormat4::NumGlyphs(ReadableFontData* data,
+                                        int32_t table_offset) {
+  int32_t num_glyphs = data->ReadULongAsInt(table_offset +
+      EblcTable::Offset::kIndexSubTable4_numGlyphs);
+  return num_glyphs;
+}
+
+/******************************************************************************
+ * IndexSubTableFormat4::CodeOffsetPair related class
+ ******************************************************************************/
+IndexSubTableFormat4::CodeOffsetPair::CodeOffsetPair(int32_t glyph_code,
+                                                     int32_t offset)
+    : glyph_code_(glyph_code), offset_(offset) {
+}
+
+IndexSubTableFormat4::CodeOffsetPairBuilder::CodeOffsetPairBuilder()
+    : CodeOffsetPair(0, 0) {
+}
+
+IndexSubTableFormat4::CodeOffsetPairBuilder::CodeOffsetPairBuilder(
+    int32_t glyph_code, int32_t offset)
+    : CodeOffsetPair(glyph_code, offset) {
+}
+
+bool IndexSubTableFormat4::CodeOffsetPairGlyphCodeComparator::operator()(
+    const CodeOffsetPair& lhs, const CodeOffsetPair& rhs) {
+  return lhs.glyph_code() < rhs.glyph_code();
+}
+
+/******************************************************************************
+ * IndexSubTableFormat4::Builder class
+ ******************************************************************************/
+IndexSubTableFormat4::Builder::~Builder() {
+}
+
+int32_t IndexSubTableFormat4::Builder::NumGlyphs() {
+  return GetOffsetArray()->size() - 1;
+}
+
+int32_t IndexSubTableFormat4::Builder::GlyphLength(int32_t glyph_id) {
+  int32_t loca = CheckGlyphRange(glyph_id);
+  if (loca == -1) {
+    return 0;
+  }
+  int32_t pair_index = FindCodeOffsetPair(glyph_id);
+  if (pair_index == -1) {
+    return 0;
+  }
+  return GetOffsetArray()->at(pair_index + 1).offset() -
+         GetOffsetArray()->at(pair_index).offset();
+}
+
+int32_t IndexSubTableFormat4::Builder::GlyphStartOffset(int32_t glyph_id) {
+  int32_t loca = CheckGlyphRange(glyph_id);
+  if (loca == -1) {
+    return -1;
+  }
+  int32_t pair_index = FindCodeOffsetPair(glyph_id);
+  if (pair_index == -1) {
+    return -1;
+  }
+  return GetOffsetArray()->at(pair_index).offset();
+}
+
+CALLER_ATTACH IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator*
+    IndexSubTableFormat4::Builder::GetIterator() {
+  Ptr<IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator> it =
+      new IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator(this);
+  return it.Detach();
+}
+
+// static
+CALLER_ATTACH IndexSubTableFormat4::Builder*
+IndexSubTableFormat4::Builder::CreateBuilder() {
+  IndexSubTableFormat4BuilderPtr output = new IndexSubTableFormat4::Builder();
+  return output.Detach();
+}
+
+// static
+CALLER_ATTACH IndexSubTableFormat4::Builder*
+IndexSubTableFormat4::Builder::CreateBuilder(ReadableFontData* data,
+                                             int32_t index_sub_table_offset,
+                                             int32_t first_glyph_index,
+                                             int32_t last_glyph_index) {
+  int32_t length = Builder::DataLength(data,
+                                       index_sub_table_offset,
+                                       first_glyph_index,
+                                       last_glyph_index);
+  ReadableFontDataPtr new_data;
+  new_data.Attach(down_cast<ReadableFontData*>(
+      data->Slice(index_sub_table_offset, length)));
+  if (new_data == NULL) {
+    return NULL;
+  }
+  IndexSubTableFormat4BuilderPtr output =
+      new IndexSubTableFormat4::Builder(new_data,
+                                        first_glyph_index,
+                                        last_glyph_index);
+  return output.Detach();
+}
+
+// static
+CALLER_ATTACH IndexSubTableFormat4::Builder*
+IndexSubTableFormat4::Builder::CreateBuilder(WritableFontData* data,
+                                             int32_t index_sub_table_offset,
+                                             int32_t first_glyph_index,
+                                             int32_t last_glyph_index) {
+  int32_t length = Builder::DataLength(data,
+                                       index_sub_table_offset,
+                                       first_glyph_index,
+                                       last_glyph_index);
+  WritableFontDataPtr new_data;
+  new_data.Attach(down_cast<WritableFontData*>(
+      data->Slice(index_sub_table_offset, length)));
+  IndexSubTableFormat4BuilderPtr output =
+      new IndexSubTableFormat4::Builder(new_data,
+                                        first_glyph_index,
+                                        last_glyph_index);
+  return output.Detach();
+}
+
+CALLER_ATTACH FontDataTable* IndexSubTableFormat4::Builder::SubBuildTable(
+    ReadableFontData* data) {
+  IndexSubTableFormat4Ptr output = new IndexSubTableFormat4(
+      data, first_glyph_index(), last_glyph_index());
+  return output.Detach();
+}
+
+void IndexSubTableFormat4::Builder::SubDataSet() {
+  Revert();
+}
+
+int32_t IndexSubTableFormat4::Builder::SubDataSizeToSerialize() {
+  if (offset_pair_array_.empty()) {
+    return InternalReadData()->Length();
+  }
+  return EblcTable::Offset::kIndexSubHeaderLength + DataSize::kULONG +
+         GetOffsetArray()->size() *
+         EblcTable::Offset::kIndexSubTable4_codeOffsetPairLength;
+}
+
+bool IndexSubTableFormat4::Builder::SubReadyToSerialize() {
+  if (!offset_pair_array_.empty()) {
+    return true;
+  }
+  return false;
+}
+
+int32_t IndexSubTableFormat4::Builder::SubSerialize(
+    WritableFontData* new_data) {
+  int32_t size = SerializeIndexSubHeader(new_data);
+  if (!model_changed()) {
+    if (InternalReadData() == NULL) {
+      return size;
+    }
+    ReadableFontDataPtr source;
+    WritableFontDataPtr target;
+    source.Attach(down_cast<ReadableFontData*>(InternalReadData()->Slice(
+        EblcTable::Offset::kIndexSubTable4_glyphArray)));
+    target.Attach(down_cast<WritableFontData*>(new_data->Slice(
+        EblcTable::Offset::kIndexSubTable4_glyphArray)));
+    size += source->CopyTo(target);
+  } else {
+    size += new_data->WriteLong(size, offset_pair_array_.size() - 1);
+    for (std::vector<CodeOffsetPairBuilder>::iterator
+             b = GetOffsetArray()->begin(), e = GetOffsetArray()->end();
+             b != e; b++) {
+      size += new_data->WriteUShort(size, b->glyph_code());
+      size += new_data->WriteUShort(size, b->offset());
+    }
+  }
+  return size;
+}
+
+void IndexSubTableFormat4::Builder::Revert() {
+  offset_pair_array_.clear();
+  IndexSubTable::Builder::Revert();
+}
+
+void IndexSubTableFormat4::Builder::SetOffsetArray(
+    const std::vector<CodeOffsetPairBuilder>& pair_array) {
+  offset_pair_array_.clear();
+  offset_pair_array_ = pair_array;
+  set_model_changed();
+}
+
+IndexSubTableFormat4::Builder::Builder()
+  : IndexSubTable::Builder(EblcTable::Offset::kIndexSubTable4_builderDataSize,
+                           Format::FORMAT_4) {
+}
+
+IndexSubTableFormat4::Builder::Builder(WritableFontData* data,
+                                       int32_t first_glyph_index,
+                                       int32_t last_glyph_index)
+    : IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
+}
+
+IndexSubTableFormat4::Builder::Builder(ReadableFontData* data,
+                                       int32_t first_glyph_index,
+                                       int32_t last_glyph_index)
+    : IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
+}
+
+std::vector<IndexSubTableFormat4::CodeOffsetPairBuilder>*
+IndexSubTableFormat4::Builder::GetOffsetArray() {
+  if (offset_pair_array_.empty()) {
+    Initialize(InternalReadData());
+    set_model_changed();
+  }
+  return &offset_pair_array_;
+}
+
+void IndexSubTableFormat4::Builder::Initialize(ReadableFontData* data) {
+  offset_pair_array_.clear();
+  if (data) {
+    int32_t num_pairs = IndexSubTableFormat4::NumGlyphs(data, 0) + 1;
+    int32_t offset = EblcTable::Offset::kIndexSubTable4_glyphArray;
+    for (int32_t i = 0; i < num_pairs; ++i) {
+      int32_t glyph_code = data->ReadUShort(offset +
+          EblcTable::Offset::kIndexSubTable4_codeOffsetPair_glyphCode);
+      int32_t glyph_offset = data->ReadUShort(offset +
+          EblcTable::Offset::kIndexSubTable4_codeOffsetPair_offset);
+      offset += EblcTable::Offset::kIndexSubTable4_codeOffsetPairLength;
+      CodeOffsetPairBuilder pair_builder(glyph_code, glyph_offset);
+      offset_pair_array_.push_back(pair_builder);
+    }
+  }
+}
+
+int32_t IndexSubTableFormat4::Builder::FindCodeOffsetPair(int32_t glyph_id) {
+  std::vector<CodeOffsetPairBuilder>* pair_list = GetOffsetArray();
+  int32_t location = 0;
+  int32_t bottom = 0;
+  int32_t top = pair_list->size();
+  while (top != bottom) {
+    location = (top + bottom) / 2;
+    CodeOffsetPairBuilder* pair = &(pair_list->at(location));
+    if (glyph_id < pair->glyph_code()) {
+      // location is below current location
+      top = location;
+    } else if (glyph_id > pair->glyph_code()) {
+      // location is above current location
+      bottom = location + 1;
+    } else {
+      return location;
+    }
+  }
+  return -1;
+}
+
+// static
+int32_t IndexSubTableFormat4::Builder::DataLength(
+    ReadableFontData* data,
+    int32_t index_sub_table_offset,
+    int32_t first_glyph_index,
+    int32_t last_glyph_index) {
+  int32_t num_glyphs = IndexSubTableFormat4::NumGlyphs(data,
+                                                       index_sub_table_offset);
+  UNREFERENCED_PARAMETER(first_glyph_index);
+  UNREFERENCED_PARAMETER(last_glyph_index);
+  return EblcTable::Offset::kIndexSubTable4_glyphArray +
+         num_glyphs * EblcTable::Offset::kIndexSubTable4_codeOffsetPair_offset;
+}
+
+
+/******************************************************************************
+ * IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator class
+ ******************************************************************************/
+IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator::BitmapGlyphInfoIterator(
+    IndexSubTableFormat4::Builder* container)
+    : RefIterator<BitmapGlyphInfo, IndexSubTableFormat4::Builder,
+                  IndexSubTable::Builder>(container),
+      code_offset_pair_index_(0) {
+}
+
+bool IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator::HasNext() {
+  if (code_offset_pair_index_ <
+      (int32_t)(container()->GetOffsetArray()->size() - 1)) {
+    return true;
+  }
+  return false;
+}
+
+CALLER_ATTACH BitmapGlyphInfo*
+IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator::Next() {
+  BitmapGlyphInfoPtr output;
+  if (!HasNext()) {
+    // Note: In C++, we do not throw exception when there's no element.
+    return NULL;
+  }
+  std::vector<CodeOffsetPairBuilder>* offset_array =
+      container()->GetOffsetArray();
+  int32_t offset = offset_array->at(code_offset_pair_index_).offset();
+  int32_t next_offset = offset_array->at(code_offset_pair_index_ + 1).offset();
+  int32_t glyph_code = offset_array->at(code_offset_pair_index_).glyph_code();
+  output = new BitmapGlyphInfo(glyph_code,
+                               container()->image_data_offset(),
+                               offset,
+                               next_offset - offset,
+                               container()->image_format());
+  code_offset_pair_index_++;
+  return output.Detach();
+}
+
+}  // namespace sfntly
diff --git a/sfntly/table/bitmap/index_sub_table_format4.h b/sfntly/table/bitmap/index_sub_table_format4.h
new file mode 100644
index 0000000..efd540f
--- /dev/null
+++ b/sfntly/table/bitmap/index_sub_table_format4.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT4_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT4_H_
+
+#include "sfntly/table/bitmap/index_sub_table.h"
+
+namespace sfntly {
+
+class IndexSubTableFormat4 : public IndexSubTable,
+                             public RefCounted<IndexSubTableFormat4> {
+ public:
+  class CodeOffsetPair {
+   public:
+    int32_t glyph_code() const { return glyph_code_; }
+    int32_t offset() const { return offset_; }
+
+   protected:
+    CodeOffsetPair(int32_t glyph_code, int32_t offset);
+
+    // TODO(arthurhsu): C++ style guide prohibits protected members.
+    int32_t glyph_code_;
+    int32_t offset_;
+  };
+
+  class CodeOffsetPairBuilder : public CodeOffsetPair {
+   public:
+    CodeOffsetPairBuilder();
+    CodeOffsetPairBuilder(int32_t glyph_code, int32_t offset);
+    void set_glyph_code(int32_t v) { glyph_code_ = v; }
+    void set_offset(int32_t v) { offset_ = v; }
+  };
+
+  class CodeOffsetPairGlyphCodeComparator {
+   public:
+    bool operator()(const CodeOffsetPair& lhs, const CodeOffsetPair& rhs);
+  };
+
+  class Builder : public IndexSubTable::Builder,
+                  public RefCounted<Builder> {
+   public:
+    class BitmapGlyphInfoIterator
+        : public RefIterator<BitmapGlyphInfo, Builder, IndexSubTable::Builder> {
+     public:
+      explicit BitmapGlyphInfoIterator(Builder* container);
+      virtual ~BitmapGlyphInfoIterator() {}
+
+      virtual bool HasNext();
+      CALLER_ATTACH virtual BitmapGlyphInfo* Next();
+
+     private:
+      int32_t code_offset_pair_index_;
+    };
+
+    virtual ~Builder();
+    virtual int32_t NumGlyphs();
+    virtual int32_t GlyphLength(int32_t glyph_id);
+    virtual int32_t GlyphStartOffset(int32_t glyph_id);
+    CALLER_ATTACH virtual BitmapGlyphInfoIterator* GetIterator();
+
+    virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+    virtual void SubDataSet();
+    virtual int32_t SubDataSizeToSerialize();
+    virtual bool SubReadyToSerialize();
+    virtual int32_t SubSerialize(WritableFontData* new_data);
+
+    void Revert();
+    void SetOffsetArray(const std::vector<CodeOffsetPairBuilder>& pair_array);
+
+    static CALLER_ATTACH Builder* CreateBuilder();
+    static CALLER_ATTACH Builder* CreateBuilder(ReadableFontData* data,
+                                                int32_t index_sub_table_offset,
+                                                int32_t first_glyph_index,
+                                                int32_t last_glyph_index);
+    static CALLER_ATTACH Builder* CreateBuilder(WritableFontData* data,
+                                                int32_t index_sub_table_offset,
+                                                int32_t first_glyph_index,
+                                                int32_t last_glyph_index);
+   private:
+    Builder();
+    Builder(WritableFontData* data,
+            int32_t first_glyph_index,
+            int32_t last_glyph_index);
+    Builder(ReadableFontData* data,
+            int32_t first_glyph_index,
+            int32_t last_glyph_index);
+    std::vector<CodeOffsetPairBuilder>* GetOffsetArray();
+    void Initialize(ReadableFontData* data);
+    int32_t FindCodeOffsetPair(int32_t glyph_id);
+
+    static int32_t DataLength(ReadableFontData* data,
+                              int32_t index_sub_table_offset,
+                              int32_t first_glyph_index,
+                              int32_t last_glyph_index);
+
+    std::vector<CodeOffsetPairBuilder> offset_pair_array_;
+  };
+
+  virtual ~IndexSubTableFormat4();
+
+  virtual int32_t NumGlyphs();
+  virtual int32_t GlyphStartOffset(int32_t glyph_id);
+  virtual int32_t GlyphLength(int32_t glyph_id);
+
+ private:
+  IndexSubTableFormat4(ReadableFontData* data,
+                       int32_t first_glyph_index,
+                       int32_t last_glyph_index);
+
+  int32_t FindCodeOffsetPair(int32_t glyph_id);
+  static int32_t NumGlyphs(ReadableFontData* data, int32_t table_offset);
+
+  friend class Builder;
+};
+typedef Ptr<IndexSubTableFormat4> IndexSubTableFormat4Ptr;
+typedef Ptr<IndexSubTableFormat4::Builder> IndexSubTableFormat4BuilderPtr;
+typedef std::vector<IndexSubTableFormat4::CodeOffsetPairBuilder>
+            CodeOffsetPairBuilderList;
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT4_H_
diff --git a/sfntly/table/bitmap/index_sub_table_format5.cc b/sfntly/table/bitmap/index_sub_table_format5.cc
new file mode 100644
index 0000000..0ca21fe
--- /dev/null
+++ b/sfntly/table/bitmap/index_sub_table_format5.cc
@@ -0,0 +1,347 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/table/bitmap/index_sub_table_format5.h"
+
+#include <algorithm>
+
+#include "sfntly/table/bitmap/eblc_table.h"
+
+namespace sfntly {
+/******************************************************************************
+ * IndexSubTableFormat5 class
+ ******************************************************************************/
+IndexSubTableFormat5::~IndexSubTableFormat5() {
+}
+
+int32_t IndexSubTableFormat5::NumGlyphs() {
+  return NumGlyphs(data_, 0);
+}
+
+int32_t IndexSubTableFormat5::GlyphStartOffset(int32_t glyph_id) {
+  int32_t check = CheckGlyphRange(glyph_id);
+  if (check == -1) {
+    return -1;
+  }
+  int32_t loca = ReadFontData()->SearchUShort(
+      EblcTable::Offset::kIndexSubTable5_glyphArray,
+      DataSize::kUSHORT,
+      NumGlyphs(),
+      glyph_id);
+  if (loca == -1) {
+    return loca;
+  }
+  return loca * ImageSize();
+}
+
+int32_t IndexSubTableFormat5::GlyphLength(int32_t glyph_id) {
+  int32_t check = CheckGlyphRange(glyph_id);
+  if (check == -1) {
+    return 0;
+  }
+  return image_size_;
+}
+
+int32_t IndexSubTableFormat5::ImageSize() {
+  return data_->ReadULongAsInt(EblcTable::Offset::kIndexSubTable5_imageSize);
+}
+
+CALLER_ATTACH BigGlyphMetrics* IndexSubTableFormat5::BigMetrics() {
+  ReadableFontDataPtr data;
+  data.Attach(down_cast<ReadableFontData*>(data_->Slice(
+      EblcTable::Offset::kIndexSubTable5_bigGlyphMetrics,
+      BigGlyphMetrics::Offset::kMetricsLength)));
+  BigGlyphMetricsPtr output = new BigGlyphMetrics(data);
+  return output.Detach();
+}
+
+IndexSubTableFormat5::IndexSubTableFormat5(ReadableFontData* data,
+                                           int32_t first_glyph_index,
+                                           int32_t last_glyph_index)
+    : IndexSubTable(data, first_glyph_index, last_glyph_index) {
+  image_size_ = data_->ReadULongAsInt(
+      EblcTable::Offset::kIndexSubTable5_imageSize);
+}
+
+// static
+int32_t IndexSubTableFormat5::NumGlyphs(ReadableFontData* data,
+                                        int32_t table_offset) {
+  int32_t num_glyphs = data->ReadULongAsInt(table_offset +
+      EblcTable::Offset::kIndexSubTable5_numGlyphs);
+  return num_glyphs;
+}
+
+/******************************************************************************
+ * IndexSubTableFormat5::Builder class
+ ******************************************************************************/
+IndexSubTableFormat5::Builder::~Builder() {
+}
+
+int32_t IndexSubTableFormat5::Builder::NumGlyphs() {
+  return GetGlyphArray()->size();
+}
+
+int32_t IndexSubTableFormat5::Builder::GlyphLength(int32_t glyph_id) {
+  UNREFERENCED_PARAMETER(glyph_id);
+  return ImageSize();
+}
+
+int32_t IndexSubTableFormat5::Builder::GlyphStartOffset(int32_t glyph_id) {
+  int32_t check = CheckGlyphRange(glyph_id);
+  if (check == -1) {
+    return -1;
+  }
+  IntegerList* glyph_array = GetGlyphArray();
+  IntegerList::iterator it = std::find(glyph_array->begin(),
+                                       glyph_array->end(),
+                                       glyph_id);
+  if (it == glyph_array->end()) {
+    return -1;
+  }
+  return (it - glyph_array->begin()) * ImageSize();
+}
+
+CALLER_ATTACH IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator*
+    IndexSubTableFormat5::Builder::GetIterator() {
+  Ptr<IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator> it =
+      new IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator(this);
+  return it.Detach();
+}
+
+// static
+CALLER_ATTACH IndexSubTableFormat5::Builder*
+IndexSubTableFormat5::Builder::CreateBuilder() {
+  IndexSubTableFormat5BuilderPtr output = new IndexSubTableFormat5::Builder();
+  return output.Detach();
+}
+
+// static
+CALLER_ATTACH IndexSubTableFormat5::Builder*
+IndexSubTableFormat5::Builder::CreateBuilder(ReadableFontData* data,
+                                             int32_t index_sub_table_offset,
+                                             int32_t first_glyph_index,
+                                             int32_t last_glyph_index) {
+  int32_t length = Builder::DataLength(data,
+                                       index_sub_table_offset,
+                                       first_glyph_index,
+                                       last_glyph_index);
+  ReadableFontDataPtr new_data;
+  new_data.Attach(down_cast<ReadableFontData*>(
+      data->Slice(index_sub_table_offset, length)));
+  if (new_data == NULL) {
+    return NULL;
+  }
+  IndexSubTableFormat5BuilderPtr output =
+      new IndexSubTableFormat5::Builder(new_data,
+                                        first_glyph_index,
+                                        last_glyph_index);
+  return output.Detach();
+}
+
+// static
+CALLER_ATTACH IndexSubTableFormat5::Builder*
+IndexSubTableFormat5::Builder::CreateBuilder(WritableFontData* data,
+                                             int32_t index_sub_table_offset,
+                                             int32_t first_glyph_index,
+                                             int32_t last_glyph_index) {
+  int32_t length = Builder::DataLength(data,
+                                       index_sub_table_offset,
+                                       first_glyph_index,
+                                       last_glyph_index);
+  WritableFontDataPtr new_data;
+  new_data.Attach(down_cast<WritableFontData*>(
+      data->Slice(index_sub_table_offset, length)));
+  IndexSubTableFormat5BuilderPtr output =
+      new IndexSubTableFormat5::Builder(new_data,
+                                        first_glyph_index,
+                                        last_glyph_index);
+  return output.Detach();
+}
+
+CALLER_ATTACH FontDataTable* IndexSubTableFormat5::Builder::SubBuildTable(
+    ReadableFontData* data) {
+  IndexSubTableFormat5Ptr output = new IndexSubTableFormat5(
+      data, first_glyph_index(), last_glyph_index());
+  return output.Detach();
+}
+
+void IndexSubTableFormat5::Builder::SubDataSet() {
+  Revert();
+}
+
+int32_t IndexSubTableFormat5::Builder::SubDataSizeToSerialize() {
+  if (glyph_array_.empty()) {
+    return InternalReadData()->Length();
+  }
+  return EblcTable::Offset::kIndexSubTable5_builderDataSize +
+         glyph_array_.size() * DataSize::kUSHORT;
+}
+
+bool IndexSubTableFormat5::Builder::SubReadyToSerialize() {
+  if (!glyph_array_.empty()) {
+    return true;
+  }
+  return false;
+}
+
+int32_t IndexSubTableFormat5::Builder::SubSerialize(
+    WritableFontData* new_data) {
+  int32_t size = SerializeIndexSubHeader(new_data);
+  if (!model_changed()) {
+    ReadableFontDataPtr source;
+    WritableFontDataPtr target;
+    source.Attach(down_cast<ReadableFontData*>(InternalReadData()->Slice(
+        EblcTable::Offset::kIndexSubTable5_imageSize)));
+    target.Attach(down_cast<WritableFontData*>(new_data->Slice(
+        EblcTable::Offset::kIndexSubTable5_imageSize)));
+    size += source->CopyTo(target);
+  } else {
+    size += new_data->WriteULong(EblcTable::Offset::kIndexSubTable5_imageSize,
+                                 ImageSize());
+    WritableFontDataPtr slice;
+    slice.Attach(down_cast<WritableFontData*>(new_data->Slice(size)));
+    size += BigMetrics()->SubSerialize(slice);
+    size += new_data->WriteULong(size, glyph_array_.size());
+    for (IntegerList::iterator b = glyph_array_.begin(), e = glyph_array_.end();
+                               b != e; b++) {
+      size += new_data->WriteUShort(size, *b);
+    }
+  }
+  return size;
+}
+
+int32_t IndexSubTableFormat5::Builder::ImageSize() {
+  return InternalReadData()->ReadULongAsInt(
+      EblcTable::Offset::kIndexSubTable5_imageSize);
+}
+
+void IndexSubTableFormat5::Builder::SetImageSize(int32_t image_size) {
+  InternalWriteData()->WriteULong(
+      EblcTable::Offset::kIndexSubTable5_imageSize, image_size);
+}
+
+BigGlyphMetrics::Builder* IndexSubTableFormat5::Builder::BigMetrics() {
+  if (metrics_ == NULL) {
+    WritableFontDataPtr data;
+    data.Attach(down_cast<WritableFontData*>(InternalWriteData()->Slice(
+        EblcTable::Offset::kIndexSubTable5_bigGlyphMetrics,
+        BigGlyphMetrics::Offset::kMetricsLength)));
+    metrics_ = new BigGlyphMetrics::Builder(data);
+    set_model_changed();
+  }
+  return metrics_;
+}
+
+IntegerList* IndexSubTableFormat5::Builder::GlyphArray() {
+  return GetGlyphArray();
+}
+
+void IndexSubTableFormat5::Builder::SetGlyphArray(const IntegerList& v) {
+  glyph_array_.clear();
+  glyph_array_ = v;
+  set_model_changed();
+}
+
+void IndexSubTableFormat5::Builder::Revert() {
+  glyph_array_.clear();
+  IndexSubTable::Builder::Revert();
+}
+
+IndexSubTableFormat5::Builder::Builder()
+    : IndexSubTable::Builder(EblcTable::Offset::kIndexSubTable5_builderDataSize,
+                             IndexSubTable::Format::FORMAT_5) {
+}
+
+IndexSubTableFormat5::Builder::Builder(WritableFontData* data,
+                                       int32_t first_glyph_index,
+                                       int32_t last_glyph_index)
+    : IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
+}
+
+IndexSubTableFormat5::Builder::Builder(ReadableFontData* data,
+                                       int32_t first_glyph_index,
+                                       int32_t last_glyph_index)
+    : IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
+}
+
+IntegerList* IndexSubTableFormat5::Builder::GetGlyphArray() {
+  if (glyph_array_.empty()) {
+    Initialize(InternalReadData());
+    set_model_changed();
+  }
+  return &glyph_array_;
+}
+
+void IndexSubTableFormat5::Builder::Initialize(ReadableFontData* data) {
+  glyph_array_.clear();
+  if (data) {
+    int32_t num_glyphs = IndexSubTableFormat5::NumGlyphs(data, 0);
+    for (int32_t i = 0; i < num_glyphs; ++i) {
+      glyph_array_.push_back(data->ReadUShort(
+          EblcTable::Offset::kIndexSubTable5_glyphArray +
+          i * DataSize::kUSHORT));
+    }
+  }
+}
+
+// static
+int32_t IndexSubTableFormat5::Builder::DataLength(
+    ReadableFontData* data,
+    int32_t index_sub_table_offset,
+    int32_t first_glyph_index,
+    int32_t last_glyph_index) {
+  int32_t num_glyphs = IndexSubTableFormat5::NumGlyphs(data,
+                                                       index_sub_table_offset);
+  UNREFERENCED_PARAMETER(first_glyph_index);
+  UNREFERENCED_PARAMETER(last_glyph_index);
+  return EblcTable::Offset::kIndexSubTable5_glyphArray +
+         num_glyphs * DataSize::kUSHORT;
+}
+
+/******************************************************************************
+ * IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator class
+ ******************************************************************************/
+IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator::BitmapGlyphInfoIterator(
+    IndexSubTableFormat5::Builder* container)
+    : RefIterator<BitmapGlyphInfo, IndexSubTableFormat5::Builder,
+                  IndexSubTable::Builder>(container),
+      offset_index_(0) {
+}
+
+bool IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator::HasNext() {
+  if (offset_index_ < (int32_t)(container()->GetGlyphArray()->size())) {
+    return true;
+  }
+  return false;
+}
+
+CALLER_ATTACH BitmapGlyphInfo*
+IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator::Next() {
+  BitmapGlyphInfoPtr output;
+  if (!HasNext()) {
+    // Note: In C++, we do not throw exception when there's no element.
+    return NULL;
+  }
+  output = new BitmapGlyphInfo(container()->GetGlyphArray()->at(offset_index_),
+                               container()->image_data_offset(),
+                               offset_index_ * container()->ImageSize(),
+                               container()->ImageSize(),
+                               container()->image_format());
+  offset_index_++;
+  return output.Detach();
+}
+
+}  // namespace sfntly
diff --git a/sfntly/table/bitmap/index_sub_table_format5.h b/sfntly/table/bitmap/index_sub_table_format5.h
new file mode 100644
index 0000000..a39e88c
--- /dev/null
+++ b/sfntly/table/bitmap/index_sub_table_format5.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT5_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT5_H_
+
+#include "sfntly/table/bitmap/big_glyph_metrics.h"
+#include "sfntly/table/bitmap/index_sub_table.h"
+
+namespace sfntly {
+
+class IndexSubTableFormat5 : public IndexSubTable,
+                             public RefCounted<IndexSubTableFormat5> {
+ public:
+  class Builder : public IndexSubTable::Builder,
+                  public RefCounted<Builder> {
+   public:
+    class BitmapGlyphInfoIterator
+        : public RefIterator<BitmapGlyphInfo, Builder, IndexSubTable::Builder> {
+     public:
+      explicit BitmapGlyphInfoIterator(Builder* container);
+      virtual ~BitmapGlyphInfoIterator() {}
+
+      virtual bool HasNext();
+      CALLER_ATTACH virtual BitmapGlyphInfo* Next();
+
+     private:
+      int32_t offset_index_;
+    };
+    virtual ~Builder();
+    virtual int32_t NumGlyphs();
+    virtual int32_t GlyphLength(int32_t glyph_id);
+    virtual int32_t GlyphStartOffset(int32_t glyph_id);
+    CALLER_ATTACH virtual BitmapGlyphInfoIterator* GetIterator();
+
+    virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+    virtual void SubDataSet();
+    virtual int32_t SubDataSizeToSerialize();
+    virtual bool SubReadyToSerialize();
+    virtual int32_t SubSerialize(WritableFontData* new_data);
+
+    int32_t ImageSize();
+    void SetImageSize(int32_t image_size);
+    BigGlyphMetrics::Builder* BigMetrics();
+    IntegerList* GlyphArray();
+    void SetGlyphArray(const IntegerList& v);
+
+    static CALLER_ATTACH Builder* CreateBuilder();
+    static CALLER_ATTACH Builder* CreateBuilder(ReadableFontData* data,
+                                                int32_t index_sub_table_offset,
+                                                int32_t first_glyph_index,
+                                                int32_t last_glyph_index);
+    static CALLER_ATTACH Builder* CreateBuilder(WritableFontData* data,
+                                                int32_t index_sub_table_offset,
+                                                int32_t first_glyph_index,
+                                                int32_t last_glyph_index);
+   protected:
+    void Revert();
+
+   private:
+    Builder();
+    Builder(WritableFontData* data,
+            int32_t first_glyph_index,
+            int32_t last_glyph_index);
+    Builder(ReadableFontData* data,
+            int32_t first_glyph_index,
+            int32_t last_glyph_index);
+
+    IntegerList* GetGlyphArray();
+    void Initialize(ReadableFontData* data);
+
+    static int32_t DataLength(ReadableFontData* data,
+                              int32_t index_sub_table_offset,
+                              int32_t first_glyph_index,
+                              int32_t last_glyph_index);
+
+    IntegerList glyph_array_;
+    BigGlyphMetricsBuilderPtr metrics_;
+  };
+  virtual ~IndexSubTableFormat5();
+
+  virtual int32_t NumGlyphs();
+  virtual int32_t GlyphStartOffset(int32_t glyph_id);
+  virtual int32_t GlyphLength(int32_t glyph_id);
+
+  int32_t ImageSize();
+  CALLER_ATTACH BigGlyphMetrics* BigMetrics();
+
+ private:
+  IndexSubTableFormat5(ReadableFontData* data,
+                       int32_t first_glyph_index,
+                       int32_t last_glyph_index);
+
+  static int32_t NumGlyphs(ReadableFontData* dta, int32_t table_offset);
+
+  int32_t image_size_;
+
+  friend class Builder;
+};
+typedef Ptr<IndexSubTableFormat5> IndexSubTableFormat5Ptr;
+typedef Ptr<IndexSubTableFormat5::Builder> IndexSubTableFormat5BuilderPtr;
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT5_H_
diff --git a/sfntly/table/bitmap/simple_bitmap_glyph.cc b/sfntly/table/bitmap/simple_bitmap_glyph.cc
new file mode 100644
index 0000000..87031a1
--- /dev/null
+++ b/sfntly/table/bitmap/simple_bitmap_glyph.cc
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/table/bitmap/simple_bitmap_glyph.h"
+
+namespace sfntly {
+
+SimpleBitmapGlyph::SimpleBitmapGlyph(ReadableFontData* data, int32_t format)
+    : BitmapGlyph(data, format) {
+}
+
+SimpleBitmapGlyph::~SimpleBitmapGlyph() {
+}
+
+SimpleBitmapGlyph::Builder::Builder(ReadableFontData* data, int32_t format)
+    : BitmapGlyph::Builder(data, format) {
+}
+
+SimpleBitmapGlyph::Builder::Builder(WritableFontData* data, int32_t format)
+    : BitmapGlyph::Builder(data, format) {
+}
+
+SimpleBitmapGlyph::Builder::~Builder() {
+}
+
+CALLER_ATTACH FontDataTable*
+SimpleBitmapGlyph::Builder::SubBuildTable(ReadableFontData* data) {
+  Ptr<SimpleBitmapGlyph> glyph = new SimpleBitmapGlyph(data, format());
+  return glyph.Detach();
+}
+
+}  // namespace sfntly
diff --git a/sfntly/table/bitmap/simple_bitmap_glyph.h b/sfntly/table/bitmap/simple_bitmap_glyph.h
new file mode 100644
index 0000000..56ede10
--- /dev/null
+++ b/sfntly/table/bitmap/simple_bitmap_glyph.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_SIMPLE_BITMAP_GLYPH_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_SIMPLE_BITMAP_GLYPH_H_
+
+#include "sfntly/table/bitmap/bitmap_glyph.h"
+
+namespace sfntly {
+
+class SimpleBitmapGlyph : public BitmapGlyph,
+                          public RefCounted<SimpleBitmapGlyph> {
+ public:
+  class Builder : public BitmapGlyph::Builder,
+                  public RefCounted<Builder> {
+   public:
+    Builder(WritableFontData* data, int32_t format);
+    Builder(ReadableFontData* data, int32_t format);
+    virtual ~Builder();
+
+    virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+  };
+
+  SimpleBitmapGlyph(ReadableFontData* data, int32_t format);
+  virtual ~SimpleBitmapGlyph();
+};
+typedef Ptr<SimpleBitmapGlyph> SimpleBitmapGlyphPtr;
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_SIMPLE_BITMAP_GLYPH_H_
diff --git a/sfntly/table/bitmap/small_glyph_metrics.cc b/sfntly/table/bitmap/small_glyph_metrics.cc
new file mode 100644
index 0000000..0f3c1e9
--- /dev/null
+++ b/sfntly/table/bitmap/small_glyph_metrics.cc
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/table/bitmap/small_glyph_metrics.h"
+
+namespace sfntly {
+/******************************************************************************
+ * SmallGlyphMetrics class
+ ******************************************************************************/
+SmallGlyphMetrics::SmallGlyphMetrics(ReadableFontData* data)
+    : GlyphMetrics(data) {
+}
+
+SmallGlyphMetrics::~SmallGlyphMetrics() {
+}
+
+int32_t SmallGlyphMetrics::Height() {
+  return data_->ReadByte(Offset::kHeight);
+}
+
+int32_t SmallGlyphMetrics::Width() {
+  return data_->ReadByte(Offset::kWidth);
+}
+
+int32_t SmallGlyphMetrics::BearingX() {
+  return data_->ReadByte(Offset::kBearingX);
+}
+
+int32_t SmallGlyphMetrics::BearingY() {
+  return data_->ReadByte(Offset::kBearingY);
+}
+
+int32_t SmallGlyphMetrics::Advance() {
+  return data_->ReadByte(Offset::kAdvance);
+}
+
+/******************************************************************************
+ * SmallGlyphMetrics::Builder class
+ ******************************************************************************/
+SmallGlyphMetrics::Builder::Builder(WritableFontData* data)
+    : GlyphMetrics::Builder(data) {
+}
+
+SmallGlyphMetrics::Builder::Builder(ReadableFontData* data)
+    : GlyphMetrics::Builder(data) {
+}
+
+SmallGlyphMetrics::Builder::~Builder() {
+}
+
+int32_t SmallGlyphMetrics::Builder::Height() {
+  return InternalReadData()->ReadByte(Offset::kHeight);
+}
+
+void SmallGlyphMetrics::Builder::SetHeight(byte_t height) {
+  InternalWriteData()->WriteByte(Offset::kHeight, height);
+}
+
+int32_t SmallGlyphMetrics::Builder::Width() {
+  return InternalReadData()->ReadByte(Offset::kWidth);
+}
+
+void SmallGlyphMetrics::Builder::SetWidth(byte_t width) {
+  InternalWriteData()->WriteByte(Offset::kWidth, width);
+}
+
+int32_t SmallGlyphMetrics::Builder::BearingX() {
+  return InternalReadData()->ReadByte(Offset::kBearingX);
+}
+
+void SmallGlyphMetrics::Builder::SetBearingX(byte_t bearing) {
+  InternalWriteData()->WriteByte(Offset::kBearingX, bearing);
+}
+
+int32_t SmallGlyphMetrics::Builder::BearingY() {
+  return InternalReadData()->ReadByte(Offset::kBearingY);
+}
+
+void SmallGlyphMetrics::Builder::SetBearingY(byte_t bearing) {
+  InternalWriteData()->WriteByte(Offset::kBearingY, bearing);
+}
+
+int32_t SmallGlyphMetrics::Builder::Advance() {
+  return InternalReadData()->ReadByte(Offset::kAdvance);
+}
+
+void SmallGlyphMetrics::Builder::SetAdvance(byte_t advance) {
+  InternalWriteData()->WriteByte(Offset::kAdvance, advance);
+}
+
+CALLER_ATTACH FontDataTable*
+    SmallGlyphMetrics::Builder::SubBuildTable(ReadableFontData* data) {
+  SmallGlyphMetricsPtr output = new SmallGlyphMetrics(data);
+  return output.Detach();
+}
+
+void SmallGlyphMetrics::Builder::SubDataSet() {
+  // NOP.
+}
+
+int32_t SmallGlyphMetrics::Builder::SubDataSizeToSerialize() {
+  return 0;
+}
+
+bool SmallGlyphMetrics::Builder::SubReadyToSerialize() {
+  return false;
+}
+
+int32_t SmallGlyphMetrics::Builder::SubSerialize(WritableFontData* new_data) {
+  return Data()->CopyTo(new_data);
+}
+
+}  // namespace sfntly
diff --git a/sfntly/table/bitmap/small_glyph_metrics.h b/sfntly/table/bitmap/small_glyph_metrics.h
new file mode 100644
index 0000000..ea13720
--- /dev/null
+++ b/sfntly/table/bitmap/small_glyph_metrics.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_SMALL_GLYPH_METRICS_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_SMALL_GLYPH_METRICS_H_
+
+#include "sfntly/port/refcount.h"
+#include "sfntly/table/bitmap/glyph_metrics.h"
+
+namespace sfntly {
+
+class SmallGlyphMetrics : public GlyphMetrics,
+                          public RefCounted<SmallGlyphMetrics> {
+ public:
+  struct Offset {
+    enum {
+      kMetricsLength = 5,
+      kHeight = 0,
+      kWidth = 1,
+      kBearingX = 2,
+      kBearingY = 3,
+      kAdvance = 4,
+    };
+  };
+
+  class Builder : public GlyphMetrics::Builder,
+                  public RefCounted<Builder> {
+   public:
+    // Constructor scope altered to public because C++ does not allow base
+    // class to instantiate derived class with protected constructors.
+    explicit Builder(WritableFontData* data);
+    explicit Builder(ReadableFontData* data);
+    virtual ~Builder();
+
+    int32_t Height();
+    void SetHeight(byte_t height);
+    int32_t Width();
+    void SetWidth(byte_t width);
+    int32_t BearingX();
+    void SetBearingX(byte_t bearing);
+    int32_t BearingY();
+    void SetBearingY(byte_t bearing);
+    int32_t Advance();
+    void SetAdvance(byte_t advance);
+
+    virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+    virtual void SubDataSet();
+    virtual int32_t SubDataSizeToSerialize();
+    virtual bool SubReadyToSerialize();
+    virtual int32_t SubSerialize(WritableFontData* new_data);
+  };
+
+  explicit SmallGlyphMetrics(ReadableFontData* data);
+  virtual ~SmallGlyphMetrics();
+
+  int32_t Height();
+  int32_t Width();
+  int32_t BearingX();
+  int32_t BearingY();
+  int32_t Advance();
+};
+typedef Ptr<SmallGlyphMetrics> SmallGlyphMetricsPtr;
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_SMALL_GLYPH_METRICS_H_
diff --git a/sfntly/table/byte_array_table_builder.cc b/sfntly/table/byte_array_table_builder.cc
new file mode 100644
index 0000000..631a05f
--- /dev/null
+++ b/sfntly/table/byte_array_table_builder.cc
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/table/byte_array_table_builder.h"
+
+namespace sfntly {
+
+ByteArrayTableBuilder::~ByteArrayTableBuilder() {}
+
+int32_t ByteArrayTableBuilder::ByteValue(int32_t index) {
+  ReadableFontDataPtr data = InternalReadData();
+  if (data == NULL) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IOException("No font data for the table");
+#endif
+    return -1;
+  }
+  return data->ReadByte(index);
+}
+
+void ByteArrayTableBuilder::SetByteValue(int32_t index, byte_t b) {
+  WritableFontDataPtr data = InternalWriteData();
+  if (data == NULL) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IOException("No font data for the table");
+#endif
+    return;
+  }
+  data->WriteByte(index, b);
+}
+
+int32_t ByteArrayTableBuilder::ByteCount() {
+  ReadableFontDataPtr data = InternalReadData();
+  if (data == NULL) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IOException("No font data for the table");
+#endif
+    return 0;
+  }
+  return data->Length();
+}
+
+ByteArrayTableBuilder::ByteArrayTableBuilder(Header* header,
+                                               WritableFontData* data)
+    : TableBasedTableBuilder(header, data) {
+}
+
+ByteArrayTableBuilder::ByteArrayTableBuilder(Header* header,
+                                               ReadableFontData* data)
+    : TableBasedTableBuilder(header, data) {
+}
+
+ByteArrayTableBuilder::ByteArrayTableBuilder(Header* header)
+    : TableBasedTableBuilder(header) {
+}
+
+}  // namespace sfntly
diff --git a/sfntly/table/byte_array_table_builder.h b/sfntly/table/byte_array_table_builder.h
new file mode 100644
index 0000000..42d27a8
--- /dev/null
+++ b/sfntly/table/byte_array_table_builder.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_BYTE_ARRAY_TABLE_BUILDER_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BYTE_ARRAY_TABLE_BUILDER_H_
+
+#include "sfntly/table/table_based_table_builder.h"
+
+namespace sfntly {
+
+// An abstract builder base for byte array based tables.
+class ByteArrayTableBuilder : public TableBasedTableBuilder {
+ public:
+  virtual ~ByteArrayTableBuilder();
+
+  // Get the byte value at the specified index. The index is relative to the
+  // start of the table.
+  // @param index index relative to the start of the table
+  // @return byte value at the given index
+  virtual int32_t ByteValue(int32_t index);
+
+  // Set the byte value at the specified index. The index is relative to the
+  // start of the table.
+  // @param index index relative to the start of the table
+  // @param b byte value to set
+  virtual void SetByteValue(int32_t index, byte_t b);
+
+  // Get the number of bytes set for this table. It may include padding bytes at
+  // the end.
+  virtual int32_t ByteCount();
+
+ protected:
+  ByteArrayTableBuilder(Header* header, WritableFontData* data);
+  ByteArrayTableBuilder(Header* header, ReadableFontData* data);
+  explicit ByteArrayTableBuilder(Header* header);
+};
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_BYTE_ARRAY_TABLE_BUILDER_H_
diff --git a/sfntly/table/core/cmap_table.cc b/sfntly/table/core/cmap_table.cc
new file mode 100644
index 0000000..1c83d2e
--- /dev/null
+++ b/sfntly/table/core/cmap_table.cc
@@ -0,0 +1,1287 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+// type.h needs to be included first because of building issues on Windows
+// Type aliases we delcare are defined in other headers and make the build
+// fail otherwise.
+#include "sfntly/port/type.h"
+#include "sfntly/table/core/cmap_table.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <utility>
+
+#include "sfntly/font.h"
+#include "sfntly/math/font_math.h"
+#include "sfntly/port/endian.h"
+#include "sfntly/port/exception_type.h"
+#include "sfntly/table/core/name_table.h"
+
+namespace sfntly {
+
+const int32_t CMapTable::NOTDEF = 0;
+
+CMapTable::CMapId CMapTable::WINDOWS_BMP = {
+  PlatformId::kWindows,
+  WindowsEncodingId::kUnicodeUCS2
+};
+CMapTable::CMapId CMapTable::WINDOWS_UCS4 = {
+  PlatformId::kWindows,
+  WindowsEncodingId::kUnicodeUCS4
+};
+CMapTable::CMapId CMapTable::MAC_ROMAN = {
+  PlatformId::kWindows,
+  MacintoshEncodingId::kRoman
+};
+
+/******************************************************************************
+ * CMapTable class
+ ******************************************************************************/
+CMapTable::CMapTable(Header* header, ReadableFontData* data)
+  : SubTableContainerTable(header, data) {
+}
+
+CMapTable::~CMapTable() {}
+
+CALLER_ATTACH CMapTable::CMap* CMapTable::GetCMap(const int32_t index) {
+  if (index < 0 || index > NumCMaps()) {
+#ifndef SFNTLY_NO_EXCEPTION
+    throw IndexOutOfBoundException("Requested CMap index is out of bounds.");
+#else
+    return NULL;
+#endif
+  }
+  int32_t platform_id = PlatformId(index);
+  int32_t encoding_id = EncodingId(index);
+  CMapId cmap_id = NewCMapId(platform_id, encoding_id);
+  int32_t offset_ = Offset(index);
+  Ptr<FontDataTable::Builder> cmap_builder =
+      (CMap::Builder::GetBuilder(data_, offset_, cmap_id));
+  if (!cmap_builder) {
+#ifndef SFNTLY_NO_EXCEPTION
+    throw NoSuchElementException("Cannot find builder for requested CMap.");
+#else
+    return NULL;
+#endif
+  }
+  return down_cast<CMapTable::CMap*>(cmap_builder->Build());
+}
+
+CALLER_ATTACH CMapTable::CMap* CMapTable::GetCMap(const int32_t platform_id,
+                                                  const int32_t encoding_id) {
+  return GetCMap(NewCMapId(platform_id, encoding_id));
+}
+
+CALLER_ATTACH CMapTable::CMap*
+CMapTable::GetCMap(const CMapTable::CMapId cmap_id) {
+  CMapIdFilter id_filter(cmap_id);
+  CMapIterator cmap_iterator(this, &id_filter);
+  // There can only be one cmap with a particular CMapId
+  if (cmap_iterator.HasNext()) {
+    Ptr<CMapTable::CMap> cmap;
+    cmap.Attach(cmap_iterator.Next());
+    return cmap.Detach();
+  }
+#ifndef SFNTLY_NO_EXCEPTION
+  throw NoSuchElementException();
+#else
+  return NULL;
+#endif
+}
+
+int32_t CMapTable::Version() {
+  return data_->ReadUShort(Offset::kVersion);
+}
+
+int32_t CMapTable::NumCMaps() {
+  return data_->ReadUShort(Offset::kNumTables);
+}
+
+CMapTable::CMapId CMapTable::GetCMapId(int32_t index) {
+  return NewCMapId(PlatformId(index), EncodingId(index));
+}
+
+int32_t CMapTable::PlatformId(int32_t index) {
+  return data_->ReadUShort(Offset::kEncodingRecordPlatformId +
+                           OffsetForEncodingRecord(index));
+}
+
+int32_t CMapTable::EncodingId(int32_t index) {
+  return data_->ReadUShort(Offset::kEncodingRecordEncodingId +
+                           OffsetForEncodingRecord(index));
+}
+
+int32_t CMapTable::Offset(int32_t index) {
+  return data_->ReadULongAsInt(Offset::kEncodingRecordOffset +
+                               OffsetForEncodingRecord(index));
+}
+
+int32_t CMapTable::OffsetForEncodingRecord(int32_t index) {
+  return Offset::kEncodingRecordStart + index * Offset::kEncodingRecordSize;
+}
+
+CMapTable::CMapId CMapTable::NewCMapId(int32_t platform_id,
+                                       int32_t encoding_id) {
+  CMapId result;
+  result.platform_id = platform_id;
+  result.encoding_id = encoding_id;
+  return result;
+}
+
+CMapTable::CMapId CMapTable::NewCMapId(const CMapId& obj) {
+  CMapId result;
+  result.platform_id = obj.platform_id;
+  result.encoding_id = obj.encoding_id;
+  return result;
+}
+
+/******************************************************************************
+ * CMapTable::CMapIterator class
+ ******************************************************************************/
+CMapTable::CMapIterator::CMapIterator(CMapTable* table,
+                                      const CMapFilter* filter)
+    : table_index_(0), filter_(filter), table_(table) {
+}
+
+bool CMapTable::CMapIterator::HasNext() {
+  if (!filter_) {
+    if (table_index_ < table_->NumCMaps()) {
+      return true;
+    }
+    return false;
+  }
+
+  for (; table_index_ < table_->NumCMaps(); ++table_index_) {
+    if (filter_->accept(table_->GetCMapId(table_index_))) {
+      return true;
+    }
+  }
+  return false;
+}
+
+CALLER_ATTACH CMapTable::CMap* CMapTable::CMapIterator::Next() {
+  if (!HasNext()) {
+#ifndef SFNTLY_NO_EXCEPTION
+    throw NoSuchElementException();
+#else
+    return NULL;
+#endif
+  }
+  CMapPtr next_cmap;
+  next_cmap.Attach(table_->GetCMap(table_index_++));
+  if (next_cmap == NULL) {
+#ifndef SFNTLY_NO_EXCEPTION
+    throw NoSuchElementException("Error during the creation of the CMap");
+#else
+    return NULL;
+#endif
+  }
+  return next_cmap.Detach();
+}
+
+/******************************************************************************
+ * CMapTable::CMapId class
+ ******************************************************************************/
+
+/******************************************************************************
+ * CMapTable::CMapIdComparator class
+ ******************************************************************************/
+
+bool CMapTable::CMapIdComparator::operator()(const CMapId& lhs,
+                                             const CMapId& rhs) const {
+  return ((lhs.platform_id << 8 | lhs.encoding_id) >
+      (rhs.platform_id << 8 | rhs.encoding_id));
+}
+
+/******************************************************************************
+ * CMapTable::CMapIdFilter class
+ ******************************************************************************/
+CMapTable::CMapIdFilter::CMapIdFilter(const CMapId wanted_id)
+    : wanted_id_(wanted_id),
+      comparator_(NULL) {
+}
+
+CMapTable::CMapIdFilter::CMapIdFilter(const CMapId wanted_id,
+                                      const CMapIdComparator* comparator)
+    : wanted_id_(wanted_id),
+      comparator_(comparator) {
+}
+
+bool CMapTable::CMapIdFilter::accept(const CMapId& cmap_id) const {
+  if (!comparator_)
+    return wanted_id_ == cmap_id;
+  return (*comparator_)(wanted_id_, cmap_id);
+}
+
+/******************************************************************************
+ * CMapTable::CMap class
+ ******************************************************************************/
+CMapTable::CMap::CMap(ReadableFontData* data, int32_t format,
+                      const CMapId& cmap_id)
+    : SubTable(data), format_(format), cmap_id_(cmap_id) {
+}
+
+CMapTable::CMap::~CMap() {
+}
+
+/******************************************************************************
+ * CMapTable::CMap::Builder class
+ ******************************************************************************/
+CMapTable::CMap::Builder::~Builder() {
+}
+
+CALLER_ATTACH CMapTable::CMap::Builder*
+    CMapTable::CMap::Builder::GetBuilder(ReadableFontData* data, int32_t offset,
+                                         const CMapId& cmap_id) {
+  // NOT IMPLEMENTED: Java enum value validation
+  int32_t format = data->ReadUShort(offset);
+  CMapBuilderPtr builder;
+  switch (format) {
+    case CMapFormat::kFormat0:
+      builder.Attach(CMapFormat0::Builder::NewInstance(data, offset, cmap_id));
+      break;
+    case CMapFormat::kFormat2:
+#if defined (SFNTLY_DEBUG_CMAP)
+      fprintf(stderr, "Requesting Format2 builder, but it's unsupported; "
+              "returning NULL\n");
+#endif
+      break;
+    case CMapFormat::kFormat4:
+      builder.Attach(CMapFormat4::Builder::NewInstance(data, offset, cmap_id));
+      break;
+    default:
+#ifdef SFNTLY_DEBUG_CMAP
+      fprintf(stderr, "Unknown builder format requested\n");
+#endif
+      break;
+  }
+  return builder.Detach();
+}
+
+CALLER_ATTACH CMapTable::CMap::Builder*
+CMapTable::CMap::Builder::GetBuilder(int32_t format, const CMapId& cmap_id) {
+  Ptr<CMapTable::CMap::Builder> builder;
+  switch (format) {
+    case CMapFormat::kFormat0:
+      builder.Attach(CMapFormat0::Builder::NewInstance(cmap_id));
+      break;
+    case CMapFormat::kFormat2:
+#if defined (SFNTLY_DEBUG_CMAP)
+      fprintf(stderr, "Requesting Format2 builder, but it's unsupported; "
+              "returning NULL\n");
+#endif
+      break;
+    case CMapFormat::kFormat4:
+      builder.Attach(CMapFormat4::Builder::NewInstance(cmap_id));
+      break;
+    default:
+#ifdef SFNTLY_DEBUG_CMAP
+      fprintf(stderr, "Unknown builder format requested\n");
+#endif
+      break;
+  }
+  return builder.Detach();
+}
+
+CMapTable::CMap::Builder::Builder(ReadableFontData* data,
+                                  int32_t format,
+                                  const CMapId& cmap_id)
+    : SubTable::Builder(data),
+      format_(format),
+      cmap_id_(cmap_id),
+      language_(0) {
+}
+
+CMapTable::CMap::Builder::Builder(WritableFontData* data,
+                                  int32_t format,
+                                  const CMapId& cmap_id)
+    : SubTable::Builder(data),
+      format_(format),
+      cmap_id_(cmap_id),
+      language_(0) {
+}
+
+int32_t CMapTable::CMap::Builder::SubSerialize(WritableFontData* new_data) {
+  return InternalReadData()->CopyTo(new_data);
+}
+
+bool CMapTable::CMap::Builder::SubReadyToSerialize() {
+  return true;
+}
+
+int32_t CMapTable::CMap::Builder::SubDataSizeToSerialize() {
+  ReadableFontDataPtr read_data = InternalReadData();
+  if (!read_data)
+    return 0;
+  return read_data->Length();
+}
+
+void CMapTable::CMap::Builder::SubDataSet() {
+  // NOP
+}
+
+/******************************************************************************
+ * CMapTable::CMapFormat0
+ ******************************************************************************/
+CMapTable::CMapFormat0::~CMapFormat0() {
+}
+
+int32_t CMapTable::CMapFormat0::Language() {
+  return 0;
+}
+
+int32_t CMapTable::CMapFormat0::GlyphId(int32_t character) {
+  if (character < 0 || character > 255) {
+    return CMapTable::NOTDEF;
+  }
+  return data_->ReadUByte(character + Offset::kFormat0GlyphIdArray);
+}
+
+CMapTable::CMapFormat0::CMapFormat0(ReadableFontData* data,
+                                    const CMapId& cmap_id)
+    : CMap(data, CMapFormat::kFormat0, cmap_id) {
+}
+
+CMapTable::CMap::CharacterIterator* CMapTable::CMapFormat0::Iterator() {
+  return new CMapTable::CMapFormat0::CharacterIterator(0, 0xff);
+}
+
+
+/******************************************************************************
+ * CMapTable::CMapFormat0::CharacterIterator
+ ******************************************************************************/
+CMapTable::CMapFormat0::CharacterIterator::CharacterIterator(int32_t start,
+                                                             int32_t end)
+    : character_(start),
+    max_character_(end) {
+}
+
+CMapTable::CMapFormat0::CharacterIterator::~CharacterIterator() {}
+
+bool CMapTable::CMapFormat0::CharacterIterator::HasNext() {
+  return character_ < max_character_;
+}
+
+int32_t CMapTable::CMapFormat0::CharacterIterator::Next() {
+  if (HasNext())
+    return character_++;
+#ifndef SFNTLY_NO_EXCEPTION
+  throw NoSuchElementException("No more characters to iterate.");
+#endif
+  return -1;
+}
+
+/******************************************************************************
+ * CMapTable::CMapFormat0::Builder
+ ******************************************************************************/
+// static
+CALLER_ATTACH CMapTable::CMapFormat0::Builder*
+CMapTable::CMapFormat0::Builder::NewInstance(WritableFontData* data,
+                                             int32_t offset,
+                                             const CMapId& cmap_id) {
+  WritableFontDataPtr wdata;
+  if (data) {
+    wdata.Attach(down_cast<WritableFontData*>(
+        data->Slice(offset,
+                    data->ReadUShort(offset + Offset::kFormat0Length))));
+  }
+  return new Builder(wdata, CMapFormat::kFormat0, cmap_id);
+}
+
+// static
+CALLER_ATTACH CMapTable::CMapFormat0::Builder*
+CMapTable::CMapFormat0::Builder::NewInstance(ReadableFontData* data,
+                                             int32_t offset,
+                                             const CMapId& cmap_id) {
+  ReadableFontDataPtr rdata;
+  if (data) {
+    rdata.Attach(down_cast<ReadableFontData*>(
+        data->Slice(offset,
+                    data->ReadUShort(offset + Offset::kFormat0Length))));
+  }
+  return new Builder(rdata, CMapFormat::kFormat0, cmap_id);
+}
+
+// static
+CALLER_ATTACH CMapTable::CMapFormat0::Builder*
+CMapTable::CMapFormat0::Builder::NewInstance(const CMapId& cmap_id) {
+  return new Builder(cmap_id);
+}
+
+// Always call NewInstance instead of the constructor for creating a new builder
+// object! This refactoring avoids memory leaks when slicing the font data.
+CMapTable::CMapFormat0::Builder::Builder(WritableFontData* data, int32_t offset,
+                                         const CMapId& cmap_id)
+    : CMapTable::CMap::Builder(data, CMapFormat::kFormat0, cmap_id) {
+  UNREFERENCED_PARAMETER(offset);
+}
+
+CMapTable::CMapFormat0::Builder::Builder(
+    ReadableFontData* data,
+    int32_t offset,
+    const CMapId& cmap_id)
+    : CMapTable::CMap::Builder(data, CMapFormat::kFormat0, cmap_id) {
+  UNREFERENCED_PARAMETER(offset);
+}
+
+CMapTable::CMapFormat0::Builder::Builder(const CMapId& cmap_id)
+    : CMap::Builder(reinterpret_cast<ReadableFontData*>(NULL),
+                    CMapFormat::kFormat0,
+                    cmap_id) {
+}
+
+CMapTable::CMapFormat0::Builder::~Builder() {
+}
+
+CALLER_ATTACH FontDataTable*
+    CMapTable::CMapFormat0::Builder::SubBuildTable(ReadableFontData* data) {
+  FontDataTablePtr table = new CMapFormat0(data, cmap_id());
+  return table.Detach();
+}
+
+/******************************************************************************
+ * CMapTable::CMapFormat2
+ ******************************************************************************/
+CMapTable::CMapFormat2::~CMapFormat2() {
+}
+
+int32_t CMapTable::CMapFormat2::Language() {
+  return 0;
+}
+
+int32_t CMapTable::CMapFormat2::GlyphId(int32_t character) {
+  if (character > 0xffff) {
+    return CMapTable::NOTDEF;
+  }
+
+  uint32_t c = ToBE32(character);
+  byte_t high_byte = (c >> 8) & 0xff;
+  byte_t low_byte = c & 0xff;
+  int32_t offset = SubHeaderOffset(high_byte);
+
+  if (offset == 0) {
+    low_byte = high_byte;
+    high_byte = 0;
+  }
+
+  int32_t first_code = FirstCode(high_byte);
+  int32_t entry_count = EntryCount(high_byte);
+
+  if (low_byte < first_code || low_byte >= first_code + entry_count) {
+    return CMapTable::NOTDEF;
+  }
+
+  int32_t id_range_offset = IdRangeOffset(high_byte);
+
+  // position of idRangeOffset + value of idRangeOffset + index for low byte
+  // = firstcode
+  int32_t p_location = (offset + Offset::kFormat2SubHeader_idRangeOffset) +
+      id_range_offset +
+      (low_byte - first_code) * DataSize::kUSHORT;
+  int p = data_->ReadUShort(p_location);
+  if (p == 0) {
+    return CMapTable::NOTDEF;
+  }
+
+  if (offset == 0) {
+    return p;
+  }
+  int id_delta = IdDelta(high_byte);
+  return (p + id_delta) % 65536;
+}
+
+int32_t CMapTable::CMapFormat2::BytesConsumed(int32_t character) {
+  uint32_t c = ToBE32(character);
+  int32_t high_byte = (c >> 8) & 0xff;
+  int32_t offset = SubHeaderOffset(high_byte);
+  return (offset == 0) ? 1 : 2;
+}
+
+CMapTable::CMapFormat2::CMapFormat2(ReadableFontData* data,
+                                    const CMapId& cmap_id)
+    : CMap(data, CMapFormat::kFormat2, cmap_id) {
+}
+
+int32_t CMapTable::CMapFormat2::SubHeaderOffset(int32_t sub_header_index) {
+  return data_->ReadUShort(Offset::kFormat2SubHeaderKeys +
+                           sub_header_index * DataSize::kUSHORT);
+}
+
+int32_t CMapTable::CMapFormat2::FirstCode(int32_t sub_header_index) {
+  int32_t sub_header_offset = SubHeaderOffset(sub_header_index);
+  return data_->ReadUShort(sub_header_offset +
+                           Offset::kFormat2SubHeaderKeys +
+                           Offset::kFormat2SubHeader_firstCode);
+}
+
+int32_t CMapTable::CMapFormat2::EntryCount(int32_t sub_header_index) {
+  int32_t sub_header_offset = SubHeaderOffset(sub_header_index);
+  return data_->ReadUShort(sub_header_offset +
+                           Offset::kFormat2SubHeaderKeys +
+                           Offset::kFormat2SubHeader_entryCount);
+}
+
+int32_t CMapTable::CMapFormat2::IdRangeOffset(int32_t sub_header_index) {
+  int32_t sub_header_offset = SubHeaderOffset(sub_header_index);
+  return data_->ReadUShort(sub_header_offset +
+                           Offset::kFormat2SubHeaderKeys +
+                           Offset::kFormat2SubHeader_idRangeOffset);
+}
+
+int32_t CMapTable::CMapFormat2::IdDelta(int32_t sub_header_index) {
+  int32_t sub_header_offset = SubHeaderOffset(sub_header_index);
+  return data_->ReadUShort(sub_header_offset +
+                           Offset::kFormat2SubHeaderKeys +
+                           Offset::kFormat2SubHeader_idDelta);
+}
+
+CMapTable::CMap::CharacterIterator* CMapTable::CMapFormat2::Iterator() {
+  // UNIMPLEMENTED
+  return NULL;
+}
+
+/******************************************************************************
+ * CMapTable::CMapFormat2::Builder
+ ******************************************************************************/
+CMapTable::CMapFormat2::Builder::Builder(WritableFontData* data,
+                                         int32_t offset,
+                                         const CMapId& cmap_id)
+    : CMapTable::CMap::Builder(data ? down_cast<WritableFontData*>(
+                                   data->Slice(offset, data->ReadUShort(
+                                       offset + Offset::kFormat0Length)))
+                               : reinterpret_cast<WritableFontData*>(NULL),
+                               CMapFormat::kFormat2, cmap_id) {
+  // TODO(arthurhsu): FIXIT: heavy lifting and leak, need fix.
+}
+
+CMapTable::CMapFormat2::Builder::Builder(ReadableFontData* data,
+                                         int32_t offset,
+                                         const CMapId& cmap_id)
+    : CMapTable::CMap::Builder(data ? down_cast<ReadableFontData*>(
+                                   data->Slice(offset, data->ReadUShort(
+                                       offset + Offset::kFormat0Length)))
+                               : reinterpret_cast<ReadableFontData*>(NULL),
+                               CMapFormat::kFormat2, cmap_id) {
+  // TODO(arthurhsu): FIXIT: heavy lifting and leak, need fix.
+}
+
+CMapTable::CMapFormat2::Builder::~Builder() {
+}
+
+CALLER_ATTACH FontDataTable*
+    CMapTable::CMapFormat2::Builder::SubBuildTable(ReadableFontData* data) {
+  FontDataTablePtr table = new CMapFormat2(data, cmap_id());
+  return table.Detach();
+}
+
+/******************************************************************************
+ * CMapTable::CMapFormat4
+ ******************************************************************************/
+CMapTable::CMapFormat4::CMapFormat4(ReadableFontData* data,
+                                    const CMapId& cmap_id)
+    : CMap(data, CMapFormat::kFormat4, cmap_id),
+      seg_count_(SegCount(data)),
+      start_code_offset_(StartCodeOffset(seg_count_)),
+      id_delta_offset_(IdDeltaOffset(seg_count_)),
+      glyph_id_array_offset_(GlyphIdArrayOffset(seg_count_)) {
+}
+
+CMapTable::CMapFormat4::~CMapFormat4() {
+}
+
+int32_t CMapTable::CMapFormat4::GlyphId(int32_t character) {
+  int32_t segment = data_->SearchUShort(StartCodeOffset(seg_count_),
+                                        DataSize::kUSHORT,
+                                        Offset::kFormat4EndCount,
+                                        DataSize::kUSHORT,
+                                        seg_count_,
+                                        character);
+  if (segment == -1) {
+    return CMapTable::NOTDEF;
+  }
+  int32_t start_code = StartCode(segment);
+  return RetrieveGlyphId(segment, start_code, character);
+}
+
+int32_t CMapTable::CMapFormat4::RetrieveGlyphId(int32_t segment,
+                                                int32_t start_code,
+                                                int32_t character) {
+  if (character < start_code) {
+    return CMapTable::NOTDEF;
+  }
+  int32_t id_range_offset = IdRangeOffset(segment);
+  if (id_range_offset == 0) {
+    return (character + IdDelta(segment)) % 65536;
+  }
+  return data_->ReadUShort(id_range_offset +
+                           IdRangeOffsetLocation(segment) +
+                           2 * (character - start_code));
+}
+
+int32_t CMapTable::CMapFormat4::seg_count() {
+  return seg_count_;
+}
+
+int32_t CMapTable::CMapFormat4::Length() {
+  return Length(data_);
+}
+
+int32_t CMapTable::CMapFormat4::StartCode(int32_t segment) {
+  if (!IsValidIndex(segment)) {
+    return -1;
+  }
+  return StartCode(data_.p_, seg_count_, segment);
+}
+
+// static
+int32_t CMapTable::CMapFormat4::Language(ReadableFontData* data) {
+  int32_t language = data->ReadUShort(Offset::kFormat4Language);
+  return language;
+}
+
+// static
+int32_t CMapTable::CMapFormat4::Length(ReadableFontData* data) {
+  int32_t length = data->ReadUShort(Offset::kFormat4Length);
+  return length;
+}
+
+// static
+int32_t CMapTable::CMapFormat4::SegCount(ReadableFontData* data) {
+  int32_t seg_count = data->ReadUShort(Offset::kFormat4SegCountX2) / 2;
+  return seg_count;
+}
+
+// static
+int32_t CMapTable::CMapFormat4::StartCode(ReadableFontData* data,
+                                          int32_t seg_count,
+                                          int32_t index) {
+  int32_t start_code = data->ReadUShort(StartCodeOffset(seg_count) +
+                                        index * DataSize::kUSHORT);
+  return start_code;
+}
+
+// static
+int32_t CMapTable::CMapFormat4::StartCodeOffset(int32_t seg_count) {
+  int32_t start_code_offset = Offset::kFormat4EndCount +
+      (seg_count + 1) * DataSize::kUSHORT;
+  return start_code_offset;
+}
+
+// static
+int32_t CMapTable::CMapFormat4::EndCode(ReadableFontData* data,
+                                        int32_t seg_count,
+                                        int32_t index) {
+  UNREFERENCED_PARAMETER(seg_count);
+  int32_t end_code = data->ReadUShort(Offset::kFormat4EndCount +
+                                      index * DataSize::kUSHORT);
+  return end_code;
+}
+
+// static
+int32_t CMapTable::CMapFormat4::IdDelta(ReadableFontData* data,
+                                        int32_t seg_count,
+                                        int32_t index) {
+  int32_t id_delta = data->ReadUShort(IdDeltaOffset(seg_count) +
+                                      index * DataSize::kUSHORT);
+  return id_delta;
+}
+
+// static
+int32_t CMapTable::CMapFormat4::IdDeltaOffset(int32_t seg_count) {
+  int32_t id_delta_offset =
+      Offset::kFormat4EndCount + (2 * seg_count + 1) * DataSize::kUSHORT;
+  return id_delta_offset;
+}
+
+// static
+int32_t CMapTable::CMapFormat4::IdRangeOffset(ReadableFontData* data,
+                                              int32_t seg_count,
+                                              int32_t index) {
+  int32_t id_range_offset =
+      data->ReadUShort(IdRangeOffsetOffset(seg_count)
+                       + index * DataSize::kUSHORT);
+  return id_range_offset;
+}
+
+// static
+int32_t CMapTable::CMapFormat4::IdRangeOffsetOffset(int32_t seg_count) {
+  int32_t id_range_offset_offset =
+      Offset::kFormat4EndCount + (2 * seg_count + 1) * DataSize::kUSHORT +
+      seg_count * DataSize::kSHORT;
+  return id_range_offset_offset;
+}
+
+// static
+int32_t CMapTable::CMapFormat4::GlyphIdArrayOffset(int32_t seg_count) {
+  int32_t glyph_id_array_offset =
+      Offset::kFormat4EndCount + (3 * seg_count + 1) * DataSize::kUSHORT +
+      seg_count * DataSize::kSHORT;
+  return glyph_id_array_offset;
+}
+
+int32_t CMapTable::CMapFormat4::EndCode(int32_t segment) {
+  if (IsValidIndex(segment)) {
+    return EndCode(data_, seg_count_, segment);
+  }
+#if defined (SFNTLY_NO_EXCEPTION)
+  return -1;
+#else
+  throw IllegalArgumentException();
+#endif
+}
+
+bool CMapTable::CMapFormat4::IsValidIndex(int32_t segment) {
+  if (segment < 0 || segment >= seg_count_) {
+#if defined (SFNTLY_NO_EXCEPTION)
+    return false;
+#else
+    throw IllegalArgumentException();
+#endif
+  }
+  return true;
+}
+
+int32_t CMapTable::CMapFormat4::IdDelta(int32_t segment) {
+  if (IsValidIndex(segment))
+    return IdDelta(data_, seg_count_, segment);
+  return -1;
+}
+
+int32_t CMapTable::CMapFormat4::IdRangeOffset(int32_t segment) {
+  if (IsValidIndex(segment))
+    return data_->ReadUShort(IdRangeOffsetLocation(segment));
+  return -1;
+}
+
+int32_t CMapTable::CMapFormat4::IdRangeOffsetLocation(int32_t segment) {
+  if (IsValidIndex(segment))
+    return IdRangeOffsetOffset(seg_count_) + segment * DataSize::kUSHORT;
+  return -1;
+}
+
+int32_t CMapTable::CMapFormat4::GlyphIdArray(int32_t index) {
+  return data_->ReadUShort(glyph_id_array_offset_ + index * DataSize::kUSHORT);
+}
+
+int32_t CMapTable::CMapFormat4::Language() {
+  return Language(data_);
+}
+
+
+CMapTable::CMap::CharacterIterator* CMapTable::CMapFormat4::Iterator() {
+  return new CharacterIterator(this);
+}
+
+/******************************************************************************
+ * CMapTable::CMapFormat4::CharacterIterator class
+ ******************************************************************************/
+CMapTable::CMapFormat4::CharacterIterator::CharacterIterator(
+    CMapFormat4* parent)
+    : parent_(parent),
+      segment_index_(0),
+      first_char_in_segment_(-1),
+      last_char_in_segment_(-1),
+      next_char_(-1),
+      next_char_set_(false) {
+}
+
+bool CMapTable::CMapFormat4::CharacterIterator::HasNext() {
+  if (next_char_set_)
+    return true;
+  while (segment_index_ < parent_->seg_count_) {
+    if (first_char_in_segment_ < 0) {
+      first_char_in_segment_ = parent_->StartCode(segment_index_);
+      last_char_in_segment_ = parent_->EndCode(segment_index_);
+      next_char_ = first_char_in_segment_;
+      next_char_set_ = true;
+      return true;
+    }
+    if (next_char_ < last_char_in_segment_) {
+      next_char_++;
+      next_char_set_ = true;
+      return true;
+    }
+    segment_index_++;
+    first_char_in_segment_ = -1;
+  }
+  return false;
+}
+
+int32_t CMapTable::CMapFormat4::CharacterIterator::Next() {
+  if (!next_char_set_) {
+    if (!HasNext()) {
+#if defined (SFNTLY_NO_EXCEPTION)
+      return -1;
+#else
+      throw NoSuchElementException("No more characters to iterate.");
+#endif
+    }
+  }
+  next_char_set_ = false;
+  return next_char_;
+}
+
+/******************************************************************************
+ * CMapTable::CMapFormat4::Builder::Segment class
+ ******************************************************************************/
+CMapTable::CMapFormat4::Builder::Segment::Segment() {}
+
+CMapTable::CMapFormat4::Builder::Segment::Segment(Segment* other)
+    : start_count_(other->start_count_),
+      end_count_(other->end_count_),
+      id_delta_(other->id_delta_),
+      id_range_offset_(other->id_range_offset_) {
+}
+
+CMapTable::CMapFormat4::Builder::Segment::Segment(int32_t start_count,
+                                                  int32_t end_count,
+                                                  int32_t id_delta,
+                                                  int32_t id_range_offset)
+    : start_count_(start_count),
+      end_count_(end_count),
+      id_delta_(id_delta),
+      id_range_offset_(id_range_offset) {
+}
+
+CMapTable::CMapFormat4::Builder::Segment::~Segment() {}
+
+int32_t CMapTable::CMapFormat4::Builder::Segment::start_count() {
+  return start_count_;
+}
+
+void
+CMapTable::CMapFormat4::Builder::Segment::set_start_count(int32_t start_count) {
+  start_count_ = start_count;
+}
+
+int32_t CMapTable::CMapFormat4::Builder::Segment::end_count() {
+  return end_count_;
+}
+
+void
+CMapTable::CMapFormat4::Builder::Segment::set_end_count(int32_t end_count) {
+  end_count_ = end_count;
+}
+
+int32_t CMapTable::CMapFormat4::Builder::Segment::id_delta() {
+  return id_delta_;
+}
+
+void
+CMapTable::CMapFormat4::Builder::Segment::set_id_delta(int32_t id_delta) {
+  id_delta_ = id_delta;
+}
+
+int32_t CMapTable::CMapFormat4::Builder::Segment::id_range_offset() {
+  return id_range_offset_;
+}
+
+void
+CMapTable::CMapFormat4::Builder::Segment::
+set_id_range_offset(int32_t id_range_offset) {
+  id_range_offset_ = id_range_offset;
+}
+
+// static
+CALLER_ATTACH SegmentList*
+CMapTable::CMapFormat4::Builder::Segment::DeepCopy(SegmentList* original) {
+  SegmentList* list = new SegmentList;
+  for (SegmentList::iterator it = original->begin(),
+           e = original->end(); it != e; ++it) {
+    list->push_back(*it);
+  }
+  return list;
+}
+
+/******************************************************************************
+ * CMapTable::CMapFormat4::Builder class
+ ******************************************************************************/
+CALLER_ATTACH CMapTable::CMapFormat4::Builder*
+CMapTable::CMapFormat4::Builder::NewInstance(ReadableFontData* data,
+                                             int32_t offset,
+                                             const CMapId& cmap_id) {
+  ReadableFontDataPtr rdata;
+  if (data) {
+    rdata.Attach
+        (down_cast<ReadableFontData*>
+         (data->Slice(offset,
+                      data->ReadUShort(offset + Offset::kFormat4Length))));
+  }
+  return new Builder(rdata, CMapFormat::kFormat4, cmap_id);
+}
+
+CALLER_ATTACH CMapTable::CMapFormat4::Builder*
+CMapTable::CMapFormat4::Builder::NewInstance(WritableFontData* data,
+                                             int32_t offset,
+                                             const CMapId& cmap_id) {
+  WritableFontDataPtr wdata;
+  if (data) {
+    wdata.Attach
+        (down_cast<WritableFontData*>
+         (data->Slice(offset,
+                      data->ReadUShort(offset + Offset::kFormat4Length))));
+  }
+  return new Builder(wdata, CMapFormat::kFormat4, cmap_id);
+}
+
+CALLER_ATTACH CMapTable::CMapFormat4::Builder*
+CMapTable::CMapFormat4::Builder::NewInstance(const CMapId& cmap_id) {
+  return new Builder(cmap_id);
+}
+
+CMapTable::CMapFormat4::Builder::Builder(ReadableFontData* data, int32_t offset,
+                                         const CMapId& cmap_id)
+    : CMap::Builder(data, CMapFormat::kFormat4, cmap_id) {
+  UNREFERENCED_PARAMETER(offset);
+}
+
+CMapTable::CMapFormat4::Builder::Builder(WritableFontData* data, int32_t offset,
+                                         const CMapId& cmap_id)
+    : CMap::Builder(data, CMapFormat::kFormat4, cmap_id) {
+  UNREFERENCED_PARAMETER(offset);
+}
+
+CMapTable::CMapFormat4::Builder::Builder(SegmentList* segments,
+                                         IntegerList* glyph_id_array,
+                                         const CMapId& cmap_id)
+    : CMap::Builder(reinterpret_cast<ReadableFontData*>(NULL),
+                    CMapFormat::kFormat4, cmap_id),
+      segments_(segments->begin(), segments->end()),
+      glyph_id_array_(glyph_id_array->begin(), glyph_id_array->end()) {
+  set_model_changed();
+}
+
+CMapTable::CMapFormat4::Builder::Builder(const CMapId& cmap_id)
+    : CMap::Builder(reinterpret_cast<ReadableFontData*>(NULL),
+                    CMapFormat::kFormat4, cmap_id) {
+}
+
+CMapTable::CMapFormat4::Builder::~Builder() {}
+
+void CMapTable::CMapFormat4::Builder::Initialize(ReadableFontData* data) {
+  if (data == NULL || data->Length() == 0)
+    return;
+
+  // build segments
+  int32_t seg_count = CMapFormat4::SegCount(data);
+  for (int32_t index = 0; index < seg_count; ++index) {
+    Ptr<Segment> segment = new Segment;
+    segment->set_start_count(CMapFormat4::StartCode(data, seg_count, index));
+#if defined SFNTLY_DEBUG_CMAP
+    fprintf(stderr, "Segment %d; start %d\n", index, segment->start_count());
+#endif
+    segment->set_end_count(CMapFormat4::EndCode(data, seg_count, index));
+    segment->set_id_delta(CMapFormat4::IdDelta(data, seg_count, index));
+    segment->set_id_range_offset(CMapFormat4::IdRangeOffset(data,
+                                                           seg_count,
+                                                           index));
+    segments_.push_back(segment);
+  }
+
+  // build glyph id array
+  int32_t glyph_id_array_offset = CMapFormat4::GlyphIdArrayOffset(seg_count);
+  int32_t glyph_id_array_length =
+      (CMapFormat4::Length(data) - glyph_id_array_offset)
+      / DataSize::kUSHORT;
+  fprintf(stderr, "id array size %d\n", glyph_id_array_length);
+  for (int32_t i = 0; i < glyph_id_array_length; i += DataSize::kUSHORT) {
+    glyph_id_array_.push_back(data->ReadUShort(glyph_id_array_offset + i));
+  }
+}
+
+SegmentList* CMapTable::CMapFormat4::Builder::segments() {
+  if (segments_.empty()) {
+    Initialize(InternalReadData());
+    set_model_changed();
+  }
+  return &segments_;
+}
+
+void CMapTable::CMapFormat4::Builder::set_segments(SegmentList* segments) {
+  segments_.assign(segments->begin(), segments->end());
+  set_model_changed();
+}
+
+IntegerList* CMapTable::CMapFormat4::Builder::glyph_id_array() {
+  if (glyph_id_array_.empty()) {
+    Initialize(InternalReadData());
+    set_model_changed();
+  }
+  return &glyph_id_array_;
+}
+
+void CMapTable::CMapFormat4::Builder::
+set_glyph_id_array(IntegerList* glyph_id_array) {
+  glyph_id_array_.assign(glyph_id_array->begin(), glyph_id_array->end());
+  set_model_changed();
+}
+
+CALLER_ATTACH FontDataTable*
+CMapTable::CMapFormat4::Builder::SubBuildTable(ReadableFontData* data) {
+  FontDataTablePtr table = new CMapFormat4(data, cmap_id());
+  return table.Detach();
+}
+
+void CMapTable::CMapFormat4::Builder::SubDataSet() {
+  segments_.clear();
+  glyph_id_array_.clear();
+  set_model_changed();
+}
+
+int32_t CMapTable::CMapFormat4::Builder::SubDataSizeToSerialize() {
+  if (!model_changed()) {
+    return CMap::Builder::SubDataSizeToSerialize();
+  }
+  int32_t size = Offset::kFormat4FixedSize + segments_.size()
+      * (3 * DataSize::kUSHORT + DataSize::kSHORT)
+      + glyph_id_array_.size() * DataSize::kSHORT;
+  return size;
+}
+
+bool CMapTable::CMapFormat4::Builder::SubReadyToSerialize() {
+  if (!model_changed()) {
+    return CMap::Builder::SubReadyToSerialize();
+  }
+  if (!segments()->empty()) {
+    return true;
+  }
+  return false;
+}
+
+int32_t
+CMapTable::CMapFormat4::Builder::SubSerialize(WritableFontData* new_data) {
+  if (!model_changed()) {
+    return CMap::Builder::SubSerialize(new_data);
+  }
+  int32_t index = 0;
+  index += new_data->WriteUShort(index, CMapFormat::kFormat4);
+  index += DataSize::kUSHORT;  // length - write this at the end
+  index += new_data->WriteUShort(index, language());
+
+  int32_t seg_count = segments_.size();
+  index += new_data->WriteUShort(index, seg_count * 2);
+  int32_t log2_seg_count = FontMath::Log2(seg_count);
+  int32_t search_range = 1 << (log2_seg_count + 1);
+  index += new_data->WriteUShort(index, search_range);
+  int32_t entry_selector = log2_seg_count;
+  index += new_data->WriteUShort(index, entry_selector);
+  int32_t range_shift = 2 * seg_count - search_range;
+  index += new_data->WriteUShort(index, range_shift);
+
+  for (int32_t i = 0; i < seg_count; ++i) {
+    index += new_data->WriteUShort(index, segments_[i]->end_count());
+  }
+  index += new_data->WriteUShort(index, 0);  // reserved ushort
+  for (int32_t i = 0; i < seg_count; ++i) {
+#if defined SFNTLY_DEBUG_CMAP
+    fprintf(stderr, "Segment %d; start %d\n", i, segments_[i]->start_count());
+#endif
+    index += new_data->WriteUShort(index, segments_[i]->start_count());
+  }
+  for (int32_t i = 0; i < seg_count; ++i) {
+    index += new_data->WriteShort(index, segments_[i]->id_delta());
+  }
+  for (int32_t i = 0; i < seg_count; ++i) {
+    index += new_data->WriteUShort(index, segments_[i]->id_range_offset());
+  }
+
+#if defined SFNTLY_DEBUG_CMAP
+  fprintf(stderr, "Glyph id array size %lu\n", glyph_id_array_.size());
+#endif
+  for (size_t i = 0; i < glyph_id_array_.size(); ++i) {
+    index += new_data->WriteUShort(index, glyph_id_array_[i]);
+  }
+
+  new_data->WriteUShort(Offset::kFormat4Length, index);
+  return index;
+}
+
+/******************************************************************************
+ * CMapTable::Builder class
+ ******************************************************************************/
+CMapTable::Builder::Builder(Header* header, WritableFontData* data)
+    : SubTableContainerTable::Builder(header, data), version_(0) {
+}
+
+CMapTable::Builder::Builder(Header* header, ReadableFontData* data)
+    : SubTableContainerTable::Builder(header, data), version_(0) {
+}
+
+CMapTable::Builder::~Builder() {
+}
+
+int32_t CMapTable::Builder::SubSerialize(WritableFontData* new_data) {
+  int32_t size = new_data->WriteUShort(CMapTable::Offset::kVersion,
+                                       version_);
+  size += new_data->WriteUShort(CMapTable::Offset::kNumTables,
+                                GetCMapBuilders()->size());
+
+  int32_t index_offset = size;
+  size += GetCMapBuilders()->size() * CMapTable::Offset::kEncodingRecordSize;
+  for (CMapBuilderMap::iterator it = GetCMapBuilders()->begin(),
+           e = GetCMapBuilders()->end(); it != e; ++it) {
+    CMapBuilderPtr b = it->second;
+    // header entry
+    index_offset += new_data->WriteUShort(index_offset, b->platform_id());
+    index_offset += new_data->WriteUShort(index_offset, b->encoding_id());
+    index_offset += new_data->WriteULong(index_offset, size);
+
+    // cmap
+    FontDataPtr slice;
+    slice.Attach(new_data->Slice(size));
+    size += b->SubSerialize(down_cast<WritableFontData*>(slice.p_));
+  }
+  return size;
+}
+
+bool CMapTable::Builder::SubReadyToSerialize() {
+  if (GetCMapBuilders()->empty())
+    return false;
+
+  // check each table
+  for (CMapBuilderMap::iterator it = GetCMapBuilders()->begin(),
+           e = GetCMapBuilders()->end(); it != e; ++it) {
+    if (!it->second->SubReadyToSerialize())
+      return false;
+  }
+  return true;
+}
+
+int32_t CMapTable::Builder::SubDataSizeToSerialize() {
+  if (GetCMapBuilders()->empty())
+    return 0;
+
+  bool variable = false;
+  int32_t size = CMapTable::Offset::kEncodingRecordStart +
+      GetCMapBuilders()->size() * CMapTable::Offset::kEncodingRecordSize;
+
+  // calculate size of each table
+  for (CMapBuilderMap::iterator it = GetCMapBuilders()->begin(),
+           e = GetCMapBuilders()->end(); it != e; ++it) {
+    int32_t cmap_size = it->second->SubDataSizeToSerialize();
+    size += abs(cmap_size);
+    variable |= cmap_size <= 0;
+  }
+  return variable ? -size : size;
+}
+
+void CMapTable::Builder::SubDataSet() {
+  GetCMapBuilders()->clear();
+  Table::Builder::set_model_changed();
+}
+
+CALLER_ATTACH FontDataTable*
+    CMapTable::Builder::SubBuildTable(ReadableFontData* data) {
+  FontDataTablePtr table = new CMapTable(header(), data);
+  return table.Detach();
+}
+
+CALLER_ATTACH CMapTable::Builder*
+    CMapTable::Builder::CreateBuilder(Header* header,
+                                      WritableFontData* data) {
+  Ptr<CMapTable::Builder> builder;
+  builder = new CMapTable::Builder(header, data);
+  return builder.Detach();
+}
+
+// static
+CALLER_ATTACH CMapTable::CMap::Builder*
+    CMapTable::Builder::CMapBuilder(ReadableFontData* data, int32_t index) {
+  if (index < 0 || index > NumCMaps(data)) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IndexOutOfBoundException(
+              "CMap table is outside of the bounds of the known tables.");
+#endif
+    return NULL;
+  }
+
+  int32_t platform_id = data->ReadUShort(Offset::kEncodingRecordPlatformId +
+                                         OffsetForEncodingRecord(index));
+  int32_t encoding_id = data->ReadUShort(Offset::kEncodingRecordEncodingId +
+                                         OffsetForEncodingRecord(index));
+  int32_t offset = data->ReadULongAsInt(Offset::kEncodingRecordOffset +
+                                        OffsetForEncodingRecord(index));
+  return CMap::Builder::GetBuilder(data, offset,
+                                   NewCMapId(platform_id, encoding_id));
+}
+
+// static
+int32_t CMapTable::Builder::NumCMaps(ReadableFontData* data) {
+  if (data == NULL) {
+    return 0;
+  }
+  return data->ReadUShort(Offset::kNumTables);
+}
+
+int32_t CMapTable::Builder::NumCMaps() {
+  return GetCMapBuilders()->size();
+}
+
+void CMapTable::Builder::Initialize(ReadableFontData* data) {
+  int32_t num_cmaps = NumCMaps(data);
+  for (int32_t i = 0; i < num_cmaps; ++i) {
+    CMapTable::CMap::Builder* cmap_builder = CMapBuilder(data, i);
+    if (!cmap_builder)
+      continue;
+    cmap_builders_[cmap_builder->cmap_id()] = cmap_builder;
+  }
+}
+
+CMapTable::CMap::Builder* CMapTable::Builder::NewCMapBuilder(
+    const CMapId& cmap_id,
+    ReadableFontData* data) {
+  Ptr<WritableFontData> wfd;
+  wfd.Attach(WritableFontData::CreateWritableFontData(data->Size()));
+  data->CopyTo(wfd.p_);
+  CMapTable::CMapBuilderPtr builder;
+  builder.Attach(CMap::Builder::GetBuilder(wfd.p_, 0, cmap_id));
+  CMapBuilderMap* cmap_builders = CMapTable::Builder::GetCMapBuilders();
+  cmap_builders->insert(std::make_pair(cmap_id, builder.p_));
+  return builder.Detach();
+}
+
+CMapTable::CMap::Builder*
+CMapTable::Builder::NewCMapBuilder(int32_t format, const CMapId& cmap_id) {
+  Ptr<CMapTable::CMap::Builder> cmap_builder;
+  cmap_builder.Attach(CMap::Builder::GetBuilder(format, cmap_id));
+  CMapBuilderMap* cmap_builders = CMapTable::Builder::GetCMapBuilders();
+  cmap_builders->insert(std::make_pair(cmap_id, cmap_builder.p_));
+  return cmap_builder.Detach();
+}
+
+CMapTable::CMap::Builder*
+CMapTable::Builder::CMapBuilder(const CMapId& cmap_id) {
+  CMapBuilderMap* cmap_builders = this->GetCMapBuilders();
+  CMapBuilderMap::iterator builder = cmap_builders->find(cmap_id);
+  if (builder != cmap_builders->end())
+    return builder->second;
+#ifndef SFNTLY_NO_EXCEPTION
+  throw NoSuchElementException("No builder found for cmap_id");
+#else
+  return NULL;
+#endif
+}
+
+CMapTable::CMapBuilderMap* CMapTable::Builder::GetCMapBuilders() {
+  if (cmap_builders_.empty()) {
+    Initialize(InternalReadData());
+    set_model_changed();
+  }
+  return &cmap_builders_;
+}
+
+}  // namespace sfntly
diff --git a/sfntly/table/core/cmap_table.h b/sfntly/table/core/cmap_table.h
new file mode 100644
index 0000000..b264b07
--- /dev/null
+++ b/sfntly/table/core/cmap_table.h
@@ -0,0 +1,709 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_CMAP_TABLE_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_CMAP_TABLE_H_
+
+// type.h needs to be included first because of building issues on Windows
+// Type aliases we delcare are defined in other headers and make the build
+// fail otherwise.
+#include "sfntly/port/type.h"
+#include <vector>
+#include <map>
+
+#include "sfntly/port/refcount.h"
+#include "sfntly/table/subtable.h"
+#include "sfntly/table/subtable_container_table.h"
+
+namespace sfntly {
+
+// CMap subtable formats
+struct CMapFormat {
+  enum {
+    kFormat0 = 0,
+    kFormat2 = 2,
+    kFormat4 = 4,
+    kFormat6 = 6,
+    kFormat8 = 8,
+    kFormat10 = 10,
+    kFormat12 = 12,
+    kFormat13 = 13,
+    kFormat14 = 14
+  };
+};
+
+// A CMap table
+class CMapTable : public SubTableContainerTable, public RefCounted<CMapTable> {
+public:
+  // CMapTable::CMapId
+  struct CMapId {
+    int32_t platform_id;
+    int32_t encoding_id;
+    bool operator==(const CMapId& obj) const {
+      return platform_id == obj.platform_id && encoding_id == obj.encoding_id;
+    }
+  };
+  static CMapId WINDOWS_BMP;
+  static CMapId WINDOWS_UCS4;
+  static CMapId MAC_ROMAN;
+
+  // CMapTable::CMapIdComparator
+  class CMapIdComparator {
+   public:
+    bool operator()(const CMapId& lhs, const CMapId& rhs) const;
+  };
+
+  // A filter on cmap
+  // CMapTable::CMapFilter
+  class CMapFilter {
+   public:
+    // Test on whether the cmap is acceptable or not
+    // @param cmap_id the id of the cmap
+    // @return true if the cmap is acceptable; false otherwise
+    virtual bool accept(const CMapId& cmap_id) const = 0;
+    // Make gcc -Wnon-virtual-dtor happy.
+    virtual ~CMapFilter() {}
+  };
+
+  // Filters CMaps by CMapId to implement CMapTable::get()
+  // wanted_id is the CMap we'd like to find.
+  // We compare the current CMap to it either by equality (==) or using a
+  // comparator.
+  // CMapTable::CMapIdFilter
+  class CMapIdFilter : public CMapFilter {
+   public:
+    explicit CMapIdFilter(const CMapId wanted_id);
+    CMapIdFilter(const CMapId wanted_id,
+                 const CMapIdComparator* comparator);
+    ~CMapIdFilter() {}
+    virtual bool accept(const CMapId& cmap_id) const;
+   private:
+    CMapIdFilter& operator=(const CMapIdFilter& that);
+    const CMapId wanted_id_;
+    const CMapIdComparator *comparator_;
+  };
+
+  // The abstract base class for all cmaps.
+  //
+  // CMap equality is based on the equality of the (@link {@link CMapId} that
+  // defines the CMap. In the cmap table for a font there can only be one cmap
+  // with a given cmap id (pair of platform and encoding ids) no matter what the
+  // type of the cmap is.
+  //
+  // The cmap offers CharacterIterator to allow iteration over
+  // characters that are mapped by the cmap. This iteration mostly returns the
+  // characters mapped by the cmap. It will return all characters mapped by the
+  // cmap to anything but .notdef <b>but</b> it may return some that are not
+  // mapped or are mapped to .notdef. Various cmap tables provide ranges and
+  // such to describe characters for lookup but without going the full way to
+  // mapping to the glyph id it isn't always possible to tell if a character
+  // will end up with a valid glyph id. So, some of the characters returned from
+  // the Iterator may still end up pointing to the .notdef glyph. However, the
+  // number of such characters should be small in most cases with well designed
+  // cmaps.
+  class Builder;
+  class CMap : public SubTable {
+   public:
+    // CMapTable::CMap::Builder
+    class Builder : public SubTable::Builder {
+     public:
+      virtual ~Builder();
+
+      CALLER_ATTACH static Builder*
+          GetBuilder(ReadableFontData* data,
+                     int32_t offset,
+                     const CMapId& cmap_id);
+      CALLER_ATTACH static Builder*
+          GetBuilder(int32_t format,
+                     const CMapId& cmap_id);
+
+      // Note: yes, an object is returned on stack since it's small enough.
+      virtual CMapId cmap_id() { return cmap_id_; }
+      virtual int32_t platform_id() { return cmap_id_.platform_id; }
+      virtual int32_t encoding_id() { return cmap_id_.encoding_id; }
+      virtual int32_t format() { return format_; }
+      virtual int32_t language() { return language_; }
+      virtual void set_language(int32_t language) { language_ = language; }
+
+     protected:
+      Builder(ReadableFontData* data,
+              int32_t format,
+              const CMapId& cmap_id);
+      Builder(WritableFontData* data,
+              int32_t format,
+              const CMapId& cmap_id);
+
+      virtual int32_t SubSerialize(WritableFontData* new_data);
+      virtual bool SubReadyToSerialize();
+      virtual int32_t SubDataSizeToSerialize();
+      virtual void SubDataSet();
+
+     private:
+      int32_t format_;
+      CMapId cmap_id_;
+      int32_t language_;
+
+      friend class CMapTable::Builder;
+    };
+    // Abstract CMap character iterator
+    // The fully qualified name is CMapTable::CMap::CharacterIterator
+    class CharacterIterator {
+     public:
+      virtual ~CharacterIterator() {}
+      virtual bool HasNext() = 0;
+      // Returns -1 if there are no more characters to iterate through
+      // and exceptions are turned off
+      virtual int32_t Next() = 0;
+
+     protected:
+      // Use the CMap::Iterator method below instead of directly requesting
+      // a CharacterIterator.
+      CharacterIterator() {}
+    };
+
+    CMap(ReadableFontData* data, int32_t format, const CMapId& cmap_id);
+    virtual ~CMap();
+
+    virtual CMap::CharacterIterator* Iterator() = 0;
+
+    virtual int32_t format() { return format_; }
+    virtual CMapId cmap_id() { return cmap_id_; }
+    virtual int32_t platform_id() { return cmap_id_.platform_id; }
+    virtual int32_t encoding_id() { return cmap_id_.encoding_id; }
+
+    // Get the language of the cmap.
+    //
+    // Note on the language field in 'cmap' subtables: The language field must
+    // be set to zero for all cmap subtables whose platform IDs are other than
+    // Macintosh (platform ID 1). For cmap subtables whose platform IDs are
+    // Macintosh, set this field to the Macintosh language ID of the cmap
+    // subtable plus one, or to zero if the cmap subtable is not
+    // language-specific. For example, a Mac OS Turkish cmap subtable must set
+    // this field to 18, since the Macintosh language ID for Turkish is 17. A
+    // Mac OS Roman cmap subtable must set this field to 0, since Mac OS Roman
+    // is not a language-specific encoding.
+    //
+    // @return the language id
+    virtual int32_t Language() = 0;
+
+    // Gets the glyph id for the character code provided.
+    // The character code provided must be in the encoding used by the cmap
+    // table.
+    virtual int32_t GlyphId(int32_t character) = 0;
+
+   private:
+    int32_t format_;
+    CMapId cmap_id_;
+  };
+  typedef Ptr<CMap> CMapPtr;
+  typedef Ptr<CMap::Builder> CMapBuilderPtr;
+  typedef std::map<CMapId, CMapBuilderPtr, CMapIdComparator> CMapBuilderMap;
+
+  // A cmap format 0 sub table
+  class CMapFormat0 : public CMap, public RefCounted<CMapFormat0> {
+   public:
+    // The fully qualified name is CMapTable::CMapFormat0::Builder
+    class Builder : public CMap::Builder,
+                    public RefCounted<Builder> {
+     public:
+      CALLER_ATTACH static Builder* NewInstance(ReadableFontData* data,
+                                                int32_t offset,
+                                                const CMapId& cmap_id);
+      CALLER_ATTACH static Builder* NewInstance(WritableFontData* data,
+                                                int32_t offset,
+                                                const CMapId& cmap_id);
+      CALLER_ATTACH static Builder* NewInstance(const CMapId& cmap_id);
+      virtual ~Builder();
+
+     protected:
+      virtual CALLER_ATTACH FontDataTable*
+          SubBuildTable(ReadableFontData* data);
+
+     private:
+      // When creating a new CMapFormat0 Builder, use NewInstance instead of
+      // the constructors! This avoids a memory leak when slicing the FontData.
+      Builder(ReadableFontData* data, int32_t offset, const CMapId& cmap_id);
+      Builder(WritableFontData* data, int32_t offset, const CMapId& cmap_id);
+      Builder(const CMapId& cmap_id);
+    };
+
+    // The fully qualified name is CMapTable::CMapFormat0::CharacterIterator
+    class CharacterIterator : public CMap::CharacterIterator {
+     public:
+      virtual ~CharacterIterator();
+      virtual bool HasNext();
+      virtual int32_t Next();
+
+     private:
+      CharacterIterator(int32_t start, int32_t end);
+      friend class CMapFormat0;
+      int32_t character_, max_character_;
+    };
+
+    virtual ~CMapFormat0();
+    virtual int32_t Language();
+    virtual int32_t GlyphId(int32_t character);
+    CMap::CharacterIterator* Iterator();
+
+   private:
+    CMapFormat0(ReadableFontData* data, const CMapId& cmap_id);
+  };
+
+  // A cmap format 2 sub table
+  // The format 2 cmap is used for multi-byte encodings such as SJIS,
+  // EUC-JP/KR/CN, Big5, etc.
+  class CMapFormat2 : public CMap, public RefCounted<CMapFormat2> {
+   public:
+    // CMapTable::CMapFormat2::Builder
+    class Builder : public CMap::Builder,
+                    public RefCounted<Builder> {
+     public:
+      Builder(ReadableFontData* data,
+              int32_t offset,
+              const CMapId& cmap_id);
+      Builder(WritableFontData* data,
+              int32_t offset,
+              const CMapId& cmap_id);
+      virtual ~Builder();
+
+     protected:
+      virtual CALLER_ATTACH FontDataTable*
+          SubBuildTable(ReadableFontData* data);
+    };
+    // CMapTable::CMapFormat2::CharacterIterator
+    class CharacterIterator : public CMap::CharacterIterator {
+     public:
+      virtual ~CharacterIterator();
+      virtual bool hasNext();
+      virtual int32_t next();
+
+     private:
+      CharacterIterator();
+    };
+
+    virtual int32_t Language();
+    virtual int32_t GlyphId(int32_t character);
+
+    // Returns how many bytes would be consumed by a lookup of this character
+    // with this cmap. This comes about because the cmap format 2 table is
+    // designed around multi-byte encodings such as SJIS, EUC-JP, Big5, etc.
+    // return the number of bytes consumed from this "character" - either 1 or 2
+    virtual int32_t BytesConsumed(int32_t character);
+
+    virtual ~CMapFormat2();
+
+   private:
+    CMapFormat2(ReadableFontData* data, const CMapId& cmap_id);
+
+    int32_t SubHeaderOffset(int32_t sub_header_index);
+    int32_t FirstCode(int32_t sub_header_index);
+    int32_t EntryCount(int32_t sub_header_index);
+    int32_t IdRangeOffset(int32_t sub_header_index);
+    int32_t IdDelta(int32_t sub_header_index);
+    CMap::CharacterIterator* Iterator();
+  };
+
+    // CMapTable::CMapFormat4
+  class CMapFormat4 : public CMap,
+                      public RefCounted<CMapFormat4> {
+   public:
+    // CMapTable::CMapFormat4::Builder
+    class Builder : public CMap::Builder,
+                    public RefCounted<Builder> {
+     public:
+        // CMapTable::CMapFormat4::Builder::Segment
+      class Segment : public RefCounted<Segment> {
+       public:
+        Segment();
+        explicit Segment(Segment* other);
+        Segment(int32_t start_count,
+                int32_t end_count,
+                int32_t id_delta,
+                int32_t id_range_offset);
+        ~Segment();
+
+        // @return the startCount
+        int32_t start_count();
+        // @param startCount the startCount to set
+        void set_start_count(int32_t start_count);
+        // @return the endCount
+        int32_t end_count();
+        // @param endcount the endCount to set
+        void set_end_count(int32_t end_count);
+        // @return the idDelta
+        int32_t id_delta();
+        // @param idDelta the idDelta to set
+        void set_id_delta(int32_t id_delta);
+        // @return the idRangeOffset
+        int32_t id_range_offset();
+        // @param idRangeOffset the idRangeOffset to set
+        void set_id_range_offset(int32_t id_range_offset);
+
+        static CALLER_ATTACH
+        std::vector<Ptr<Segment> >*
+        DeepCopy(std::vector<Ptr<Segment> >* original);
+
+       private:
+        int32_t start_count_;
+        int32_t end_count_;
+        int32_t id_delta_;
+        int32_t id_range_offset_;
+      };
+      typedef std::vector<Ptr<Segment> > SegmentList;
+
+      static CALLER_ATTACH Builder* NewInstance(WritableFontData* data,
+                                                int32_t offset,
+                                                const CMapId& cmap_id);
+      static CALLER_ATTACH Builder* NewInstance(ReadableFontData* data,
+                                                int32_t offset,
+                                                const CMapId& cmap_id);
+      static CALLER_ATTACH Builder* NewInstance(const CMapId& cmap_id);
+      virtual ~Builder();
+      SegmentList* segments();
+      void set_segments(SegmentList* segments);
+      IntegerList* glyph_id_array();
+      void set_glyph_id_array(IntegerList* glyph_id_array);
+
+     protected:
+      Builder(WritableFontData* data, int32_t offset, const CMapId& cmap_id);
+      Builder(ReadableFontData* data, int32_t offset, const CMapId& cmap_id);
+      Builder(SegmentList* segments, IntegerList* glyph_id_array,
+              const CMapId& cmap_id);
+      explicit Builder(const CMapId& cmap_id);
+
+      virtual CALLER_ATTACH FontDataTable* SubBuildTable(
+          ReadableFontData* data);
+      virtual void SubDataSet();
+      virtual int32_t SubDataSizeToSerialize();
+      virtual bool SubReadyToSerialize();
+      virtual int32_t SubSerialize(WritableFontData* new_data);
+
+     private:
+      void Initialize(ReadableFontData* data);
+
+      SegmentList segments_;
+      IntegerList glyph_id_array_;
+    };
+
+    CMap::CharacterIterator* Iterator();
+    // CMapTable::CMapFormat4::CharacterIterator
+    class CharacterIterator : public CMap::CharacterIterator {
+     public:
+      bool HasNext();
+      int32_t Next();
+      virtual ~CharacterIterator() {}
+
+     private:
+      explicit CharacterIterator(CMapFormat4 *parent);
+      friend CMap::CharacterIterator* CMapFormat4::Iterator();
+
+      CMapFormat4* parent_;
+      int32_t segment_index_;
+      int32_t first_char_in_segment_;
+      int32_t last_char_in_segment_;
+      int32_t next_char_;
+      bool next_char_set_;
+    };
+
+    virtual int32_t GlyphId(int32_t character);
+
+    // Lower level glyph code retrieval that requires processing the Format 4
+    // segments to use.
+    // @param segment the cmap segment
+    // @param startCode the start code for the segment
+    // @param character the character to be looked up
+    // @return the glyph id for the character; CMapTable.NOTDEF if not found
+    int32_t RetrieveGlyphId(int32_t segment,
+                            int32_t start_count,
+                            int32_t character);
+    virtual int32_t Language();
+
+    // Get the count of the number of segments in this cmap.
+    // @return the number of segments
+    int32_t seg_count();
+    int32_t Length();
+    // Get the start code for a segment.
+    // @param segment the segment in the lookup table
+    // @return the start code for a segment
+    int32_t StartCode(int32_t segment);
+    // Get the end code for a segment.
+    // @param segment the segment in the look up table
+    // @return the end code for the segment
+    int32_t EndCode(int32_t segment);
+    // Get the id delta for a segment
+    // @param segment the segment in the look up table
+    // @return the id delta for the segment
+    int32_t IdDelta(int32_t segment);
+    // Get the id range offset for a segment
+    // @param segment the segment in the look up table
+    // @return the id range offset for the segment
+    int32_t IdRangeOffset(int32_t segment);
+    // Get the location of the id range offset for a segment
+    // @param segment the segment in the look up table
+    // @return the location of the id range offset for the segment
+    int32_t IdRangeOffsetLocation(int32_t segment);
+    // Declared above to allow friending inside CharacterIterator class.
+    // CMap::CharacterIterator* Iterator();
+    virtual ~CMapFormat4();
+
+   protected:
+    CMapFormat4(ReadableFontData* data, const CMapId& cmap_id);
+
+   private:
+    static int32_t Language(ReadableFontData* data);
+    static int32_t Length(ReadableFontData* data);
+    static int32_t SegCount(ReadableFontData* data);
+    static int32_t StartCode(ReadableFontData* data,
+                             int32_t seg_count,
+                             int32_t index);
+    static int32_t StartCodeOffset(int32_t seg_count);
+    static int32_t EndCode(ReadableFontData* data,
+                           int32_t seg_count,
+                           int32_t index);
+    static int32_t IdDelta(ReadableFontData* data,
+                           int32_t seg_count,
+                           int32_t index);
+    static int32_t IdDeltaOffset(int32_t seg_count);
+    static int32_t IdRangeOffset(ReadableFontData* data,
+                                 int32_t seg_count,
+                                 int32_t index);
+    static int32_t IdRangeOffsetOffset(int32_t seg_count);
+    static int32_t GlyphIdArrayOffset(int32_t seg_count);
+    // Refactored void to bool to work without exceptions.
+    bool IsValidIndex(int32_t segment);
+    int32_t GlyphIdArray(int32_t index);
+
+    int32_t seg_count_;
+    int32_t start_code_offset_;
+    int32_t id_delta_offset_;
+    int32_t glyph_id_array_offset_;
+  };
+
+  // CMapTable::Builder
+  class Builder : public SubTableContainerTable::Builder,
+                  public RefCounted<Builder> {
+   public:
+    // Constructor scope is public because C++ does not allow base class to
+    // instantiate derived class with protected constructors.
+    Builder(Header* header, WritableFontData* data);
+    Builder(Header* header, ReadableFontData* data);
+    virtual ~Builder();
+
+    virtual int32_t SubSerialize(WritableFontData* new_data);
+    virtual bool SubReadyToSerialize();
+    virtual int32_t SubDataSizeToSerialize();
+    virtual void SubDataSet();
+    virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+
+    static CALLER_ATTACH Builder* CreateBuilder(Header* header,
+                                                WritableFontData* data);
+
+    CMap::Builder* NewCMapBuilder(const CMapId& cmap_id,
+                                  ReadableFontData* data);
+    // Create a new empty CMapBuilder of the type specified in the id.
+    CMap::Builder* NewCMapBuilder(int32_t format, const CMapId& cmap_id);
+    CMap::Builder* CMapBuilder(const CMapId& cmap_id);
+
+    int32_t NumCMaps();
+    void SetVersion(int32_t version);
+
+    CMapBuilderMap* GetCMapBuilders();
+
+   protected:
+    static CALLER_ATTACH CMap::Builder* CMapBuilder(ReadableFontData* data,
+                                                    int32_t index);
+
+   private:
+    void Initialize(ReadableFontData* data);
+    static int32_t NumCMaps(ReadableFontData* data);
+
+    int32_t version_;
+    CMapBuilderMap cmap_builders_;
+  };
+  typedef Ptr<Builder> CMapTableBuilderPtr;
+
+  class CMapIterator {
+   public:
+    // If filter is NULL, filter through all tables.
+    CMapIterator(CMapTable* table, const CMapFilter* filter);
+    bool HasNext();
+    CMap* Next();
+
+   private:
+    int32_t table_index_;
+    const CMapFilter* filter_;
+    CMapTable* table_;
+  };
+
+  // Make a CMapId from a platform_id, encoding_id pair
+  static CMapId NewCMapId(int32_t platform_id, int32_t encoding_id);
+  // Make a CMapId from another CMapId
+  static CMapId NewCMapId(const CMapId& obj);
+
+  // Get the CMap with the specified parameters if it exists.
+  // Returns NULL otherwise.
+  CALLER_ATTACH CMap* GetCMap(const int32_t index);
+  CALLER_ATTACH CMap* GetCMap(const int32_t platform_id,
+                              const int32_t encoding_id);
+  CALLER_ATTACH CMap* GetCMap(const CMapId GetCMap_id);
+
+  // Get the table version.
+  virtual int32_t Version();
+
+  // Get the number of cmaps within the CMap table.
+  virtual int32_t NumCMaps();
+
+  // Get the cmap id for the cmap with the given index.
+  // Note: yes, an object is returned on stack since it's small enough.
+  //       This function is renamed from cmapId to GetCMapId().
+  virtual CMapId GetCMapId(int32_t index);
+
+  virtual int32_t PlatformId(int32_t index);
+  virtual int32_t EncodingId(int32_t index);
+
+  // Get the offset in the table data for the cmap table with the given index.
+  // The offset is from the beginning of the table.
+  virtual int32_t Offset(int32_t index);
+
+  virtual ~CMapTable();
+
+  static const int32_t NOTDEF;
+
+ private:
+  // Offsets to specific elements in the underlying data. These offsets are
+  // relative to the start of the table or the start of sub-blocks within
+  // the table.
+  struct Offset {
+    enum {
+      kVersion = 0,
+      kNumTables = 2,
+      kEncodingRecordStart = 4,
+
+      // offsets relative to the encoding record
+      kEncodingRecordPlatformId = 0,
+      kEncodingRecordEncodingId = 2,
+      kEncodingRecordOffset = 4,
+      kEncodingRecordSize = 8,
+
+      kFormat = 0,
+
+      // Format 0: Byte encoding table
+      kFormat0Format = 0,
+      kFormat0Length = 2,
+      kFormat0Language = 4,
+      kFormat0GlyphIdArray = 6,
+
+      // Format 2: High-byte mapping through table
+      kFormat2Format = 0,
+      kFormat2Length = 2,
+      kFormat2Language = 4,
+      kFormat2SubHeaderKeys = 6,
+      kFormat2SubHeaders = 518,
+      // offset relative to the subHeader structure
+      kFormat2SubHeader_firstCode = 0,
+      kFormat2SubHeader_entryCount = 2,
+      kFormat2SubHeader_idDelta = 4,
+      kFormat2SubHeader_idRangeOffset = 6,
+      kFormat2SubHeader_structLength = 8,
+
+      // Format 4: Segment mapping to delta values
+      kFormat4Format = 0,
+      kFormat4Length = 2,
+      kFormat4Language = 4,
+      kFormat4SegCountX2 = 6,
+      kFormat4SearchRange = 8,
+      kFormat4EntrySelector = 10,
+      kFormat4RangeShift = 12,
+      kFormat4EndCount = 14,
+      kFormat4FixedSize = 16,
+
+      // format 6: Trimmed table mapping
+      kFormat6Format = 0,
+      kFormat6Length = 2,
+      kFormat6Language = 4,
+      kFormat6FirstCode = 6,
+      kFormat6EntryCount = 8,
+      kFormat6GlyphIdArray = 10,
+
+      // Format 8: mixed 16-bit and 32-bit coverage
+      kFormat8Format = 0,
+      kFormat8Length = 4,
+      kFormat8Language = 8,
+      kFormat8Is32 = 12,
+      kFormat8nGroups204 = 8204,
+      kFormat8Groups208 = 8208,
+      // offset relative to the group structure
+      kFormat8Group_startCharCode = 0,
+      kFormat8Group_endCharCode = 4,
+      kFormat8Group_startGlyphId = 8,
+      kFormat8Group_structLength = 12,
+
+      // Format 10: Trimmed array
+      kFormat10Format = 0,
+      kFormat10Length = 4,
+      kFormat10Language = 8,
+      kFormat10StartCharCode = 12,
+      kFormat10NumChars = 16,
+      kFormat10Glyphs0 = 20,
+
+      // Format 12: Segmented coverage
+      kFormat12Format = 0,
+      kFormat12Length = 4,
+      kFormat12Language = 8,
+      kFormat12nGroups = 12,
+      kFormat12Groups = 16,
+      kFormat12Groups_structLength = 12,
+      // offsets within the group structure
+      kFormat12_startCharCode = 0,
+      kFormat12_endCharCode = 4,
+      kFormat12_startGlyphId = 8,
+
+      // Format 13: Last Resort Font
+      kFormat13Format = 0,
+      kFormat13Length = 4,
+      kFormat13Language = 8,
+      kFormat13nGroups = 12,
+      kFormat13Groups = 16,
+      kFormat13Groups_structLength = 12,
+      // offsets within the group structure
+      kFormat13_startCharCode = 0,
+      kFormat13_endCharCode = 4,
+      kFormat13_glyphId = 8,
+
+      // Format 14: Unicode Variation Sequences
+      kFormat14Format = 0,
+      kFormat14Length = 2,
+
+      // TODO(stuartg): finish tables
+      // Default UVS Table
+
+      // Non-default UVS Table
+      kLast = -1
+    };
+  };
+
+  CMapTable(Header* header, ReadableFontData* data);
+
+  // Get the offset in the table data for the encoding record for the cmap with
+  // the given index. The offset is from the beginning of the table.
+  static int32_t OffsetForEncodingRecord(int32_t index);
+};
+typedef std::vector<CMapTable::CMapId> CMapIdList;
+typedef Ptr<CMapTable> CMapTablePtr;
+typedef std::vector<Ptr<CMapTable::CMapFormat4::Builder::Segment> > SegmentList;
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_CMAP_TABLE_H_
diff --git a/sfntly/table/core/font_header_table.cc b/sfntly/table/core/font_header_table.cc
new file mode 100644
index 0000000..60015ca
--- /dev/null
+++ b/sfntly/table/core/font_header_table.cc
@@ -0,0 +1,265 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/table/core/font_header_table.h"
+
+namespace sfntly {
+/******************************************************************************
+ * FontHeaderTable class
+ ******************************************************************************/
+FontHeaderTable::~FontHeaderTable() {}
+
+int32_t FontHeaderTable::TableVersion() {
+  return data_->ReadFixed(Offset::kTableVersion);
+}
+
+int32_t FontHeaderTable::FontRevision() {
+  return data_->ReadFixed(Offset::kFontRevision);
+}
+
+int64_t FontHeaderTable::ChecksumAdjustment() {
+  return data_->ReadULong(Offset::kCheckSumAdjustment);
+}
+
+int64_t FontHeaderTable::MagicNumber() {
+  return data_->ReadULong(Offset::kMagicNumber);
+}
+
+int32_t FontHeaderTable::FlagsAsInt() {
+  return data_->ReadUShort(Offset::kFlags);
+}
+
+int32_t FontHeaderTable::UnitsPerEm() {
+  return data_->ReadUShort(Offset::kUnitsPerEm);
+}
+
+int64_t FontHeaderTable::Created() {
+  return data_->ReadDateTimeAsLong(Offset::kCreated);
+}
+
+int64_t FontHeaderTable::Modified() {
+  return data_->ReadDateTimeAsLong(Offset::kModified);
+}
+
+int32_t FontHeaderTable::XMin() {
+  return data_->ReadUShort(Offset::kXMin);
+}
+
+int32_t FontHeaderTable::YMin() {
+  return data_->ReadUShort(Offset::kYMin);
+}
+
+int32_t FontHeaderTable::XMax() {
+  return data_->ReadUShort(Offset::kXMax);
+}
+
+int32_t FontHeaderTable::YMax() {
+  return data_->ReadUShort(Offset::kYMax);
+}
+
+int32_t FontHeaderTable::MacStyleAsInt() {
+  return data_->ReadUShort(Offset::kMacStyle);
+}
+
+int32_t FontHeaderTable::LowestRecPPEM() {
+  return data_->ReadUShort(Offset::kLowestRecPPEM);
+}
+
+int32_t FontHeaderTable::FontDirectionHint() {
+  return data_->ReadShort(Offset::kFontDirectionHint);
+}
+
+int32_t FontHeaderTable::IndexToLocFormat() {
+  return data_->ReadShort(Offset::kIndexToLocFormat);
+}
+
+int32_t FontHeaderTable::GlyphDataFormat() {
+  return data_->ReadShort(Offset::kGlyphDataFormat);
+}
+
+FontHeaderTable::FontHeaderTable(Header* header, ReadableFontData* data)
+    : Table(header, data) {
+  IntegerList checksum_ranges;
+  checksum_ranges.push_back(0);
+  checksum_ranges.push_back(Offset::kCheckSumAdjustment);
+  checksum_ranges.push_back(Offset::kMagicNumber);
+  data_->SetCheckSumRanges(checksum_ranges);
+}
+
+/******************************************************************************
+ * FontHeaderTable::Builder class
+ ******************************************************************************/
+FontHeaderTable::Builder::Builder(Header* header, WritableFontData* data)
+    : TableBasedTableBuilder(header, data) {
+}
+
+FontHeaderTable::Builder::Builder(Header* header, ReadableFontData* data)
+    : TableBasedTableBuilder(header, data) {
+}
+
+FontHeaderTable::Builder::~Builder() {}
+
+CALLER_ATTACH FontDataTable* FontHeaderTable::Builder::SubBuildTable(
+    ReadableFontData* data) {
+  FontDataTablePtr table = new FontHeaderTable(header(), data);
+  return table.Detach();
+}
+
+int32_t FontHeaderTable::Builder::TableVersion() {
+  return down_cast<FontHeaderTable*>(GetTable())->TableVersion();
+}
+
+void FontHeaderTable::Builder::SetTableVersion(int32_t version) {
+  InternalWriteData()->WriteFixed(Offset::kTableVersion, version);
+}
+
+int32_t FontHeaderTable::Builder::FontRevision() {
+  return down_cast<FontHeaderTable*>(GetTable())->FontRevision();
+}
+
+void FontHeaderTable::Builder::SetFontRevision(int32_t revision) {
+  InternalWriteData()->WriteFixed(Offset::kFontRevision, revision);
+}
+
+int64_t FontHeaderTable::Builder::ChecksumAdjustment() {
+  return down_cast<FontHeaderTable*>(GetTable())->ChecksumAdjustment();
+}
+
+void FontHeaderTable::Builder::SetChecksumAdjustment(int64_t adjustment) {
+  InternalWriteData()->WriteULong(Offset::kCheckSumAdjustment, adjustment);
+}
+
+int64_t FontHeaderTable::Builder::MagicNumber() {
+  return down_cast<FontHeaderTable*>(GetTable())->MagicNumber();
+}
+
+void FontHeaderTable::Builder::SetMagicNumber(int64_t magic_number) {
+  InternalWriteData()->WriteULong(Offset::kMagicNumber, magic_number);
+}
+
+int32_t FontHeaderTable::Builder::FlagsAsInt() {
+  return down_cast<FontHeaderTable*>(GetTable())->FlagsAsInt();
+}
+
+void FontHeaderTable::Builder::SetFlagsAsInt(int32_t flags) {
+  InternalWriteData()->WriteUShort(Offset::kFlags, flags);
+}
+
+int32_t FontHeaderTable::Builder::UnitsPerEm() {
+  return down_cast<FontHeaderTable*>(GetTable())->UnitsPerEm();
+}
+
+void FontHeaderTable::Builder::SetUnitsPerEm(int32_t units) {
+  InternalWriteData()->WriteUShort(Offset::kUnitsPerEm, units);
+}
+
+int64_t FontHeaderTable::Builder::Created() {
+  return down_cast<FontHeaderTable*>(GetTable())->Created();
+}
+
+void FontHeaderTable::Builder::SetCreated(int64_t date) {
+  InternalWriteData()->WriteDateTime(Offset::kCreated, date);
+}
+
+int64_t FontHeaderTable::Builder::Modified() {
+  return down_cast<FontHeaderTable*>(GetTable())->Modified();
+}
+
+void FontHeaderTable::Builder::SetModified(int64_t date) {
+  InternalWriteData()->WriteDateTime(Offset::kModified, date);
+}
+
+int32_t FontHeaderTable::Builder::XMin() {
+  return down_cast<FontHeaderTable*>(GetTable())->XMin();
+}
+
+void FontHeaderTable::Builder::SetXMin(int32_t xmin) {
+  InternalWriteData()->WriteShort(Offset::kXMin, xmin);
+}
+
+int32_t FontHeaderTable::Builder::YMin() {
+  return down_cast<FontHeaderTable*>(GetTable())->YMin();
+}
+
+void FontHeaderTable::Builder::SetYMin(int32_t ymin) {
+  InternalWriteData()->WriteShort(Offset::kYMin, ymin);
+}
+
+int32_t FontHeaderTable::Builder::XMax() {
+  return down_cast<FontHeaderTable*>(GetTable())->XMax();
+}
+
+void FontHeaderTable::Builder::SetXMax(int32_t xmax) {
+  InternalWriteData()->WriteShort(Offset::kXMax, xmax);
+}
+
+int32_t FontHeaderTable::Builder::YMax() {
+  return down_cast<FontHeaderTable*>(GetTable())->YMax();
+}
+
+void FontHeaderTable::Builder::SetYMax(int32_t ymax) {
+  InternalWriteData()->WriteShort(Offset::kYMax, ymax);
+}
+
+int32_t FontHeaderTable::Builder::MacStyleAsInt() {
+  return down_cast<FontHeaderTable*>(GetTable())->MacStyleAsInt();
+}
+
+void FontHeaderTable::Builder::SetMacStyleAsInt(int32_t style) {
+  InternalWriteData()->WriteUShort(Offset::kMacStyle, style);
+}
+
+int32_t FontHeaderTable::Builder::LowestRecPPEM() {
+  return down_cast<FontHeaderTable*>(GetTable())->LowestRecPPEM();
+}
+
+void FontHeaderTable::Builder::SetLowestRecPPEM(int32_t size) {
+  InternalWriteData()->WriteUShort(Offset::kLowestRecPPEM, size);
+}
+
+int32_t FontHeaderTable::Builder::FontDirectionHint() {
+  return down_cast<FontHeaderTable*>(GetTable())->FontDirectionHint();
+}
+
+void FontHeaderTable::Builder::SetFontDirectionHint(int32_t hint) {
+  InternalWriteData()->WriteShort(Offset::kFontDirectionHint, hint);
+}
+
+int32_t FontHeaderTable::Builder::IndexToLocFormat() {
+  return down_cast<FontHeaderTable*>(GetTable())->IndexToLocFormat();
+}
+
+void FontHeaderTable::Builder::SetIndexToLocFormat(int32_t format) {
+  InternalWriteData()->WriteShort(Offset::kIndexToLocFormat, format);
+}
+
+int32_t FontHeaderTable::Builder::GlyphDataFormat() {
+  return down_cast<FontHeaderTable*>(GetTable())->GlyphDataFormat();
+}
+
+void FontHeaderTable::Builder::SetGlyphDataFormat(int32_t format) {
+  InternalWriteData()->WriteShort(Offset::kGlyphDataFormat, format);
+}
+
+CALLER_ATTACH FontHeaderTable::Builder*
+    FontHeaderTable::Builder::CreateBuilder(Header* header,
+                                            WritableFontData* data) {
+  Ptr<FontHeaderTable::Builder> builder;
+  builder = new FontHeaderTable::Builder(header, data);
+  return builder.Detach();
+}
+
+}  // namespace sfntly
diff --git a/sfntly/table/core/font_header_table.h b/sfntly/table/core/font_header_table.h
new file mode 100644
index 0000000..841955b
--- /dev/null
+++ b/sfntly/table/core/font_header_table.h
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_FONT_HEADER_TABLE_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_FONT_HEADER_TABLE_H_
+
+#include "sfntly/table/table.h"
+#include "sfntly/table/table_based_table_builder.h"
+
+namespace sfntly {
+
+struct IndexToLocFormat {
+  enum {
+    kShortOffset = 0,
+    kLongOffset = 1
+  };
+};
+
+struct FontDirectionHint {
+  enum {
+    kFullyMixed = 0,
+    kOnlyStrongLTR = 1,
+    kStrongLTRAndNeutral = 2,
+    kOnlyStrongRTL = -1,
+    kStrongRTLAndNeutral = -2
+  };
+};
+
+class FontHeaderTable : public Table, public RefCounted<FontHeaderTable> {
+ public:
+  class Builder : public TableBasedTableBuilder, public RefCounted<Builder> {
+   public:
+    // Constructor scope altered to public because C++ does not allow base
+    // class to instantiate derived class with protected constructors.
+    Builder(Header* header, WritableFontData* data);
+    Builder(Header* header, ReadableFontData* data);
+    virtual ~Builder();
+    virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+
+    virtual int32_t TableVersion();
+    virtual void SetTableVersion(int32_t version);
+    virtual int32_t FontRevision();
+    virtual void SetFontRevision(int32_t revision);
+    virtual int64_t ChecksumAdjustment();
+    virtual void SetChecksumAdjustment(int64_t adjustment);
+    virtual int64_t MagicNumber();
+    virtual void SetMagicNumber(int64_t magic_number);
+    virtual int32_t FlagsAsInt();
+    virtual void SetFlagsAsInt(int32_t flags);
+    // TODO(arthurhsu): IMPLEMENT EnumSet<Flags> Flags()
+    // TODO(arthurhsu): IMPLEMENT setFlags(EnumSet<Flags> flags)
+    virtual int32_t UnitsPerEm();
+    virtual void SetUnitsPerEm(int32_t units);
+    virtual int64_t Created();
+    virtual void SetCreated(int64_t date);
+    virtual int64_t Modified();
+    virtual void SetModified(int64_t date);
+    virtual int32_t XMin();
+    virtual void SetXMin(int32_t xmin);
+    virtual int32_t YMin();
+    virtual void SetYMin(int32_t ymin);
+    virtual int32_t XMax();
+    virtual void SetXMax(int32_t xmax);
+    virtual int32_t YMax();
+    virtual void SetYMax(int32_t ymax);
+    virtual int32_t MacStyleAsInt();
+    virtual void SetMacStyleAsInt(int32_t style);
+    // TODO(arthurhsu): IMPLEMENT EnumSet<MacStyle> macStyle()
+    // TODO(arthurhsu): IMPLEMENT setMacStyle(EnumSet<MacStyle> style)
+    virtual int32_t LowestRecPPEM();
+    virtual void SetLowestRecPPEM(int32_t size);
+    virtual int32_t FontDirectionHint();
+    virtual void SetFontDirectionHint(int32_t hint);
+    virtual int32_t IndexToLocFormat();
+    virtual void SetIndexToLocFormat(int32_t format);
+    virtual int32_t GlyphDataFormat();
+    virtual void SetGlyphDataFormat(int32_t format);
+
+    static CALLER_ATTACH Builder* CreateBuilder(Header* header,
+                                                WritableFontData* data);
+  };
+
+  virtual ~FontHeaderTable();
+  int32_t TableVersion();
+  int32_t FontRevision();
+
+  // Get the checksum adjustment. To compute: set it to 0, sum the entire font
+  // as ULONG, then store 0xB1B0AFBA - sum.
+  int64_t ChecksumAdjustment();
+
+  // Get the magic number. Set to 0x5F0F3CF5.
+  int64_t MagicNumber();
+
+  // TODO(arthurhsu): IMPLEMENT: EnumSet<Flags>
+  int32_t FlagsAsInt();
+  // TODO(arthurhsu): IMPLEMENT: Flags() returning EnumSet<Flags>
+
+  int32_t UnitsPerEm();
+
+  // Get the created date. Number of seconds since 12:00 midnight, January 1,
+  // 1904. 64-bit integer.
+  int64_t Created();
+  // Get the modified date. Number of seconds since 12:00 midnight, January 1,
+  // 1904. 64-bit integer.
+  int64_t Modified();
+
+  // Get the x min. For all glyph bounding boxes.
+  int32_t XMin();
+  // Get the y min. For all glyph bounding boxes.
+  int32_t YMin();
+  // Get the x max. For all glyph bounding boxes.
+  int32_t XMax();
+  // Get the y max. For all glyph bounding boxes.
+  int32_t YMax();
+
+  // TODO(arthurhsu): IMPLEMENT: EnumSet<MacStyle>
+  int32_t MacStyleAsInt();
+  // TODO(arthurhsu): IMPLEMENT: macStyle() returning EnumSet<MacStyle>
+
+  int32_t LowestRecPPEM();
+  int32_t FontDirectionHint();  // Note: no AsInt() form, already int
+  int32_t IndexToLocFormat();  // Note: no AsInt() form, already int
+  int32_t GlyphDataFormat();
+
+ private:
+  struct Offset {
+    enum {
+      kTableVersion = 0,
+      kFontRevision = 4,
+      kCheckSumAdjustment = 8,
+      kMagicNumber = 12,
+      kFlags = 16,
+      kUnitsPerEm = 18,
+      kCreated = 20,
+      kModified = 28,
+      kXMin = 36,
+      kYMin = 38,
+      kXMax = 40,
+      kYMax = 42,
+      kMacStyle = 44,
+      kLowestRecPPEM = 46,
+      kFontDirectionHint = 48,
+      kIndexToLocFormat = 50,
+      kGlyphDataFormat = 52
+    };
+  };
+
+  FontHeaderTable(Header* header, ReadableFontData* data);
+};
+typedef Ptr<FontHeaderTable> FontHeaderTablePtr;
+typedef Ptr<FontHeaderTable::Builder> FontHeaderTableBuilderPtr;
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_FONT_HEADER_TABLE_H_
diff --git a/sfntly/table/core/horizontal_device_metrics_table.cc b/sfntly/table/core/horizontal_device_metrics_table.cc
new file mode 100644
index 0000000..50b0cf5
--- /dev/null
+++ b/sfntly/table/core/horizontal_device_metrics_table.cc
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/table/core/horizontal_device_metrics_table.h"
+
+namespace sfntly {
+/******************************************************************************
+ * HorizontalDeviceMetricsTable class
+ ******************************************************************************/
+HorizontalDeviceMetricsTable:: ~HorizontalDeviceMetricsTable() {}
+
+int32_t HorizontalDeviceMetricsTable::Version() {
+  return data_->ReadUShort(Offset::kVersion);
+}
+
+int32_t HorizontalDeviceMetricsTable::NumRecords() {
+  return data_->ReadShort(Offset::kNumRecords);
+}
+
+int32_t HorizontalDeviceMetricsTable::RecordSize() {
+  return data_->ReadLong(Offset::kSizeDeviceRecord);
+}
+
+int32_t HorizontalDeviceMetricsTable::PixelSize(int32_t record_index) {
+  if (record_index < 0 || record_index >= NumRecords()) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IndexOutOfBoundsException();
+#endif
+    return -1;
+  }
+  return data_->ReadUByte(Offset::kRecords + record_index * RecordSize() +
+                          Offset::kDeviceRecordPixelSize);
+}
+
+int32_t HorizontalDeviceMetricsTable::MaxWidth(int32_t record_index) {
+  if (record_index < 0 || record_index >= NumRecords()) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IndexOutOfBoundsException();
+#endif
+    return -1;
+  }
+  return data_->ReadUByte(Offset::kRecords + record_index * RecordSize() +
+                          Offset::kDeviceRecordMaxWidth);
+}
+
+int32_t HorizontalDeviceMetricsTable::Width(int32_t record_index,
+                                            int32_t glyph_num) {
+  if (record_index < 0 || record_index >= NumRecords() ||
+      glyph_num < 0 || glyph_num >= num_glyphs_) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IndexOutOfBoundsException();
+#endif
+    return -1;
+  }
+  return data_->ReadUByte(Offset::kRecords + record_index * RecordSize() +
+                          Offset::kDeviceRecordWidths + glyph_num);
+}
+
+HorizontalDeviceMetricsTable::HorizontalDeviceMetricsTable(
+    Header* header,
+    ReadableFontData* data,
+    int32_t num_glyphs)
+    : Table(header, data), num_glyphs_(num_glyphs) {
+}
+
+/******************************************************************************
+ * HorizontalDeviceMetricsTable::Builder class
+ ******************************************************************************/
+HorizontalDeviceMetricsTable::Builder::Builder(Header* header,
+                                               WritableFontData* data)
+    : TableBasedTableBuilder(header, data), num_glyphs_(-1) {
+}
+
+HorizontalDeviceMetricsTable::Builder::Builder(Header* header,
+                                               ReadableFontData* data)
+    : TableBasedTableBuilder(header, data), num_glyphs_(-1) {
+}
+
+HorizontalDeviceMetricsTable::Builder::~Builder() {}
+
+CALLER_ATTACH FontDataTable*
+HorizontalDeviceMetricsTable::Builder::SubBuildTable(ReadableFontData* data) {
+  FontDataTablePtr table = new HorizontalDeviceMetricsTable(header(), data,
+                                                            num_glyphs_);
+  return table.Detach();
+}
+
+void HorizontalDeviceMetricsTable::Builder::SetNumGlyphs(int32_t num_glyphs) {
+  if (num_glyphs < 0) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IllegalArgumentException("Number of glyphs can't be negative.");
+#endif
+    return;
+  }
+  num_glyphs_ = num_glyphs;
+  HorizontalDeviceMetricsTable* table =
+      down_cast<HorizontalDeviceMetricsTable*>(GetTable());
+  if (table) {
+    table->num_glyphs_ = num_glyphs;
+  }
+}
+
+CALLER_ATTACH HorizontalDeviceMetricsTable::Builder*
+HorizontalDeviceMetricsTable::Builder::CreateBuilder(Header* header,
+                                                     WritableFontData* data) {
+  Ptr<HorizontalDeviceMetricsTable::Builder> builder;
+  builder = new HorizontalDeviceMetricsTable::Builder(header, data);
+  return builder.Detach();
+}
+
+}  // namespace sfntly
diff --git a/sfntly/table/core/horizontal_device_metrics_table.h b/sfntly/table/core/horizontal_device_metrics_table.h
new file mode 100644
index 0000000..4a27ba0
--- /dev/null
+++ b/sfntly/table/core/horizontal_device_metrics_table.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_HORIZONTAL_DEVICE_METRICS_TABLE_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_HORIZONTAL_DEVICE_METRICS_TABLE_H_
+
+#include "sfntly/table/table.h"
+#include "sfntly/table/table_based_table_builder.h"
+
+namespace sfntly {
+
+// A Horizontal Device Metrics table - 'hdmx'
+class HorizontalDeviceMetricsTable
+    : public Table,
+      public RefCounted<HorizontalDeviceMetricsTable> {
+ public:
+  class Builder : public TableBasedTableBuilder, public RefCounted<Builder> {
+   public:
+    // Constructor scope altered to public because C++ does not allow base
+    // class to instantiate derived class with protected constructors.
+    Builder(Header* header, WritableFontData* data);
+    Builder(Header* header, ReadableFontData* data);
+    virtual ~Builder();
+    virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+
+    static CALLER_ATTACH Builder* CreateBuilder(Header* header,
+                                                WritableFontData* data);
+
+    void SetNumGlyphs(int32_t num_glyphs);
+
+   private:
+    int32_t num_glyphs_;
+  };
+
+  virtual ~HorizontalDeviceMetricsTable();
+
+  int32_t Version();
+  int32_t NumRecords();
+  int32_t RecordSize();
+  int32_t PixelSize(int32_t record_index);
+  int32_t MaxWidth(int32_t record_index);
+  int32_t Width(int32_t record_index, int32_t glyph_num);
+
+ private:
+  struct Offset {
+    enum {
+      kVersion = 0,
+      kNumRecords = 2,
+      kSizeDeviceRecord = 4,
+      kRecords = 8,
+
+      // Offsets within a device record
+      kDeviceRecordPixelSize = 0,
+      kDeviceRecordMaxWidth = 1,
+      kDeviceRecordWidths = 2,
+    };
+  };
+  HorizontalDeviceMetricsTable(Header* header,
+                               ReadableFontData* data,
+                               int32_t num_glyphs);
+
+  int32_t num_glyphs_;
+};
+typedef Ptr<HorizontalDeviceMetricsTable> HorizontalDeviceMetricsTablePtr;
+typedef Ptr<HorizontalDeviceMetricsTable::Builder>
+            HorizontalDeviceMetricsTableBuilderPtr;
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_HORIZONTAL_DEVICE_METRICS_TABLE_H_
diff --git a/sfntly/table/core/horizontal_header_table.cc b/sfntly/table/core/horizontal_header_table.cc
new file mode 100644
index 0000000..43c2058
--- /dev/null
+++ b/sfntly/table/core/horizontal_header_table.cc
@@ -0,0 +1,213 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/table/core/horizontal_header_table.h"
+
+namespace sfntly {
+/******************************************************************************
+ * HorizontalHeaderTable class
+ ******************************************************************************/
+HorizontalHeaderTable:: ~HorizontalHeaderTable() {}
+
+int32_t HorizontalHeaderTable::TableVersion() {
+  return data_->ReadFixed(Offset::kVersion);
+}
+
+int32_t HorizontalHeaderTable::Ascender() {
+  return data_->ReadShort(Offset::kAscender);
+}
+
+int32_t HorizontalHeaderTable::Descender() {
+  return data_->ReadShort(Offset::kDescender);
+}
+
+int32_t HorizontalHeaderTable::LineGap() {
+  return data_->ReadShort(Offset::kLineGap);
+}
+
+int32_t HorizontalHeaderTable::AdvanceWidthMax() {
+  return data_->ReadUShort(Offset::kAdvanceWidthMax);
+}
+
+int32_t HorizontalHeaderTable::MinLeftSideBearing() {
+  return data_->ReadShort(Offset::kMinLeftSideBearing);
+}
+
+int32_t HorizontalHeaderTable::MinRightSideBearing() {
+  return data_->ReadShort(Offset::kMinRightSideBearing);
+}
+
+int32_t HorizontalHeaderTable::XMaxExtent() {
+  return data_->ReadShort(Offset::kXMaxExtent);
+}
+
+int32_t HorizontalHeaderTable::CaretSlopeRise() {
+  return data_->ReadShort(Offset::kCaretSlopeRise);
+}
+
+int32_t HorizontalHeaderTable::CaretSlopeRun() {
+  return data_->ReadShort(Offset::kCaretSlopeRun);
+}
+
+int32_t HorizontalHeaderTable::CaretOffset() {
+  return data_->ReadShort(Offset::kCaretOffset);
+}
+
+int32_t HorizontalHeaderTable::MetricDataFormat() {
+  return data_->ReadShort(Offset::kMetricDataFormat);
+}
+
+int32_t HorizontalHeaderTable::NumberOfHMetrics() {
+  return data_->ReadUShort(Offset::kNumberOfHMetrics);
+}
+
+HorizontalHeaderTable:: HorizontalHeaderTable(Header* header,
+                                              ReadableFontData* data)
+    : Table(header, data) {
+}
+
+/******************************************************************************
+ * HorizontalHeaderTable::Builder class
+ ******************************************************************************/
+HorizontalHeaderTable::Builder::Builder(Header* header, WritableFontData* data)
+    : TableBasedTableBuilder(header, data) {
+}
+
+HorizontalHeaderTable::Builder::Builder(Header* header, ReadableFontData* data)
+    : TableBasedTableBuilder(header, data) {
+}
+
+HorizontalHeaderTable::Builder::~Builder() {}
+
+CALLER_ATTACH FontDataTable*
+    HorizontalHeaderTable::Builder::SubBuildTable(ReadableFontData* data) {
+  FontDataTablePtr table = new HorizontalHeaderTable(header(), data);
+  return table.Detach();
+}
+
+CALLER_ATTACH HorizontalHeaderTable::Builder*
+    HorizontalHeaderTable::Builder::CreateBuilder(Header* header,
+                                                  WritableFontData* data) {
+  Ptr<HorizontalHeaderTable::Builder> builder;
+  builder = new HorizontalHeaderTable::Builder(header, data);
+  return builder.Detach();
+}
+
+int32_t HorizontalHeaderTable::Builder::TableVersion() {
+  return InternalReadData()->ReadFixed(Offset::kVersion);
+}
+
+void HorizontalHeaderTable::Builder::SetTableVersion(int32_t version) {
+  InternalWriteData()->WriteFixed(Offset::kVersion, version);
+}
+
+int32_t HorizontalHeaderTable::Builder::Ascender() {
+  return InternalReadData()->ReadShort(Offset::kAscender);
+}
+
+void HorizontalHeaderTable::Builder::SetAscender(int32_t ascender) {
+  InternalWriteData()->WriteShort(Offset::kVersion, ascender);
+}
+
+int32_t HorizontalHeaderTable::Builder::Descender() {
+  return InternalReadData()->ReadShort(Offset::kDescender);
+}
+
+void HorizontalHeaderTable::Builder::SetDescender(int32_t descender) {
+  InternalWriteData()->WriteShort(Offset::kDescender, descender);
+}
+
+int32_t HorizontalHeaderTable::Builder::LineGap() {
+  return InternalReadData()->ReadShort(Offset::kLineGap);
+}
+
+void HorizontalHeaderTable::Builder::SetLineGap(int32_t line_gap) {
+  InternalWriteData()->WriteShort(Offset::kLineGap, line_gap);
+}
+
+int32_t HorizontalHeaderTable::Builder::AdvanceWidthMax() {
+  return InternalReadData()->ReadUShort(Offset::kAdvanceWidthMax);
+}
+
+void HorizontalHeaderTable::Builder::SetAdvanceWidthMax(int32_t value) {
+  InternalWriteData()->WriteUShort(Offset::kAdvanceWidthMax, value);
+}
+
+int32_t HorizontalHeaderTable::Builder::MinLeftSideBearing() {
+  return InternalReadData()->ReadShort(Offset::kMinLeftSideBearing);
+}
+
+void HorizontalHeaderTable::Builder::SetMinLeftSideBearing(int32_t value) {
+  InternalWriteData()->WriteShort(Offset::kMinLeftSideBearing, value);
+}
+
+int32_t HorizontalHeaderTable::Builder::MinRightSideBearing() {
+  return InternalReadData()->ReadShort(Offset::kMinRightSideBearing);
+}
+
+void HorizontalHeaderTable::Builder::SetMinRightSideBearing(int32_t value) {
+  InternalWriteData()->WriteShort(Offset::kMinRightSideBearing, value);
+}
+
+int32_t HorizontalHeaderTable::Builder::XMaxExtent() {
+  return InternalReadData()->ReadShort(Offset::kXMaxExtent);
+}
+
+void HorizontalHeaderTable::Builder::SetXMaxExtent(int32_t value) {
+  InternalWriteData()->WriteShort(Offset::kXMaxExtent, value);
+}
+
+int32_t HorizontalHeaderTable::Builder::CaretSlopeRise() {
+  return InternalReadData()->ReadUShort(Offset::kCaretSlopeRise);
+}
+
+void HorizontalHeaderTable::Builder::SetCaretSlopeRise(int32_t value) {
+  InternalWriteData()->WriteUShort(Offset::kCaretSlopeRise, value);
+}
+
+int32_t HorizontalHeaderTable::Builder::CaretSlopeRun() {
+  return InternalReadData()->ReadUShort(Offset::kCaretSlopeRun);
+}
+
+void HorizontalHeaderTable::Builder::SetCaretSlopeRun(int32_t value) {
+  InternalWriteData()->WriteUShort(Offset::kCaretSlopeRun, value);
+}
+
+int32_t HorizontalHeaderTable::Builder::CaretOffset() {
+  return InternalReadData()->ReadUShort(Offset::kCaretOffset);
+}
+
+void HorizontalHeaderTable::Builder::SetCaretOffset(int32_t value) {
+  InternalWriteData()->WriteUShort(Offset::kCaretOffset, value);
+}
+
+int32_t HorizontalHeaderTable::Builder::MetricDataFormat() {
+  return InternalReadData()->ReadUShort(Offset::kMetricDataFormat);
+}
+
+void HorizontalHeaderTable::Builder::SetMetricDataFormat(int32_t value) {
+  InternalWriteData()->WriteUShort(Offset::kMetricDataFormat, value);
+}
+
+int32_t HorizontalHeaderTable::Builder::NumberOfHMetrics() {
+  return InternalReadData()->ReadUShort(Offset::kNumberOfHMetrics);
+}
+
+void HorizontalHeaderTable::Builder::SetNumberOfHMetrics(int32_t value) {
+  InternalWriteData()->WriteUShort(Offset::kNumberOfHMetrics, value);
+}
+
+}  // namespace sfntly
diff --git a/sfntly/table/core/horizontal_header_table.h b/sfntly/table/core/horizontal_header_table.h
new file mode 100644
index 0000000..71f30b4
--- /dev/null
+++ b/sfntly/table/core/horizontal_header_table.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_HORIZONTAL_HEADER_TABLE_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_HORIZONTAL_HEADER_TABLE_H_
+
+#include "sfntly/table/table.h"
+#include "sfntly/table/table_based_table_builder.h"
+
+namespace sfntly {
+
+// A Horizontal Header table - 'hhea'.
+class HorizontalHeaderTable : public Table,
+                              public RefCounted<HorizontalHeaderTable> {
+ public:
+  // Builder for a Horizontal Header table - 'hhea'.
+  class Builder : public TableBasedTableBuilder, public RefCounted<Builder> {
+   public:
+    // Constructor scope altered to public because C++ does not allow base
+    // class to instantiate derived class with protected constructors.
+    Builder(Header* header, WritableFontData* data);
+    Builder(Header* header, ReadableFontData* data);
+    virtual ~Builder();
+    virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+
+    static CALLER_ATTACH Builder* CreateBuilder(Header* header,
+                                                WritableFontData* data);
+
+    int32_t TableVersion();
+    void SetTableVersion(int32_t version);
+    int32_t Ascender();
+    void SetAscender(int32_t ascender);
+    int32_t Descender();
+    void SetDescender(int32_t descender);
+    int32_t LineGap();
+    void SetLineGap(int32_t line_gap);
+    int32_t AdvanceWidthMax();
+    void SetAdvanceWidthMax(int32_t value);
+    int32_t MinLeftSideBearing();
+    void SetMinLeftSideBearing(int32_t value);
+    int32_t MinRightSideBearing();
+    void SetMinRightSideBearing(int32_t value);
+    int32_t XMaxExtent();
+    void SetXMaxExtent(int32_t value);
+    int32_t CaretSlopeRise();
+    void SetCaretSlopeRise(int32_t value);
+    int32_t CaretSlopeRun();
+    void SetCaretSlopeRun(int32_t value);
+    int32_t CaretOffset();
+    void SetCaretOffset(int32_t value);
+    int32_t MetricDataFormat();
+    void SetMetricDataFormat(int32_t value);
+    int32_t NumberOfHMetrics();
+    void SetNumberOfHMetrics(int32_t value);
+  };
+
+  virtual ~HorizontalHeaderTable();
+  int32_t TableVersion();
+  int32_t Ascender();
+  int32_t Descender();
+  int32_t LineGap();
+  int32_t AdvanceWidthMax();
+  int32_t MinLeftSideBearing();
+  int32_t MinRightSideBearing();
+  int32_t XMaxExtent();
+  int32_t CaretSlopeRise();
+  int32_t CaretSlopeRun();
+  int32_t CaretOffset();
+  int32_t MetricDataFormat();
+  int32_t NumberOfHMetrics();
+
+ private:
+  struct Offset {
+    enum {
+      kVersion = 0,
+      kAscender = 4,
+      kDescender = 6,
+      kLineGap = 8,
+      kAdvanceWidthMax = 10,
+      kMinLeftSideBearing = 12,
+      kMinRightSideBearing = 14,
+      kXMaxExtent = 16,
+      kCaretSlopeRise = 18,
+      kCaretSlopeRun = 20,
+      kCaretOffset = 22,
+      kMetricDataFormat = 32,
+      kNumberOfHMetrics = 34,
+    };
+  };
+
+  HorizontalHeaderTable(Header* header, ReadableFontData* data);
+};
+typedef Ptr<HorizontalHeaderTable> HorizontalHeaderTablePtr;
+typedef Ptr<HorizontalHeaderTable::Builder> HorizontalHeaderTableBuilderPtr;
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_HORIZONTAL_HEADER_TABLE_H_
diff --git a/sfntly/table/core/horizontal_metrics_table.cc b/sfntly/table/core/horizontal_metrics_table.cc
new file mode 100644
index 0000000..156387d
--- /dev/null
+++ b/sfntly/table/core/horizontal_metrics_table.cc
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/table/core/horizontal_metrics_table.h"
+#include "sfntly/port/exception_type.h"
+
+namespace sfntly {
+/******************************************************************************
+ * HorizontalMetricsTable class
+ ******************************************************************************/
+HorizontalMetricsTable::~HorizontalMetricsTable() {}
+
+int32_t HorizontalMetricsTable::NumberOfHMetrics() {
+  return num_hmetrics_;
+}
+
+int32_t HorizontalMetricsTable::NumberOfLSBs() {
+  return num_glyphs_ - num_hmetrics_;
+}
+
+int32_t HorizontalMetricsTable::HMetricAdvanceWidth(int32_t entry) {
+  if (entry > num_hmetrics_) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IndexOutOfBoundException();
+#endif
+    return 0;
+  }
+  int32_t offset = Offset::kHMetricsStart + (entry * Offset::kHMetricsSize) +
+                   Offset::kHMetricsAdvanceWidth;
+  return data_->ReadUShort(offset);
+}
+
+int32_t HorizontalMetricsTable::HMetricLSB(int32_t entry) {
+  if (entry > num_hmetrics_) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IndexOutOfBoundException();
+#endif
+    return 0;
+  }
+  int32_t offset = Offset::kHMetricsStart + (entry * Offset::kHMetricsSize) +
+                   Offset::kHMetricsLeftSideBearing;
+  return data_->ReadShort(offset);
+}
+
+int32_t HorizontalMetricsTable::LsbTableEntry(int32_t entry) {
+  if (entry > num_hmetrics_) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IndexOutOfBoundException();
+#endif
+    return 0;
+  }
+  int32_t offset = Offset::kHMetricsStart + (entry * Offset::kHMetricsSize) +
+                   Offset::kLeftSideBearingSize;
+  return data_->ReadShort(offset);
+}
+
+int32_t HorizontalMetricsTable::AdvanceWidth(int32_t glyph_id) {
+  if (glyph_id < num_hmetrics_) {
+    return HMetricAdvanceWidth(glyph_id);
+  }
+  return HMetricAdvanceWidth(glyph_id - num_hmetrics_);
+}
+
+int32_t HorizontalMetricsTable::LeftSideBearing(int32_t glyph_id) {
+  if (glyph_id < num_hmetrics_) {
+    return HMetricLSB(glyph_id);
+  }
+  return LsbTableEntry(glyph_id - num_hmetrics_);
+}
+
+HorizontalMetricsTable::HorizontalMetricsTable(Header* header,
+                                               ReadableFontData* data,
+                                               int32_t num_hmetrics,
+                                               int32_t num_glyphs)
+    : Table(header, data),
+      num_hmetrics_(num_hmetrics),
+      num_glyphs_(num_glyphs) {
+}
+
+/******************************************************************************
+ * HorizontalMetricsTable::Builder class
+ ******************************************************************************/
+HorizontalMetricsTable::Builder::Builder(Header* header, WritableFontData* data)
+    : TableBasedTableBuilder(header, data), num_hmetrics_(-1), num_glyphs_(-1) {
+}
+
+HorizontalMetricsTable::Builder::Builder(Header* header, ReadableFontData* data)
+    : TableBasedTableBuilder(header, data), num_hmetrics_(-1), num_glyphs_(-1) {
+}
+
+HorizontalMetricsTable::Builder::~Builder() {}
+
+CALLER_ATTACH FontDataTable*
+    HorizontalMetricsTable::Builder::SubBuildTable(ReadableFontData* data) {
+  FontDataTablePtr table =
+      new HorizontalMetricsTable(header(), data, num_hmetrics_, num_glyphs_);
+  return table.Detach();
+}
+
+CALLER_ATTACH HorizontalMetricsTable::Builder*
+    HorizontalMetricsTable::Builder::CreateBuilder(Header* header,
+                                                   WritableFontData* data) {
+  Ptr<HorizontalMetricsTable::Builder> builder;
+  builder = new HorizontalMetricsTable::Builder(header, data);
+  return builder.Detach();
+}
+
+void HorizontalMetricsTable::Builder::SetNumberOfHMetrics(
+    int32_t num_hmetrics) {
+  assert(num_hmetrics >= 0);
+  num_hmetrics_ = num_hmetrics;
+  HorizontalMetricsTable* table =
+      down_cast<HorizontalMetricsTable*>(this->GetTable());
+  table->num_hmetrics_ = num_hmetrics;
+}
+
+void HorizontalMetricsTable::Builder::SetNumGlyphs(int32_t num_glyphs) {
+  assert(num_glyphs >= 0);
+  num_glyphs_ = num_glyphs;
+  HorizontalMetricsTable* table =
+      down_cast<HorizontalMetricsTable*>(this->GetTable());
+  table->num_glyphs_ = num_glyphs;
+}
+
+}  // namespace sfntly
diff --git a/sfntly/table/core/horizontal_metrics_table.h b/sfntly/table/core/horizontal_metrics_table.h
new file mode 100644
index 0000000..44b51f2
--- /dev/null
+++ b/sfntly/table/core/horizontal_metrics_table.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_HORIZONTAL_METRICS_TABLE_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_HORIZONTAL_METRICS_TABLE_H_
+
+#include "sfntly/table/table.h"
+#include "sfntly/table/table_based_table_builder.h"
+
+namespace sfntly {
+
+// A Horizontal Metrics table - 'hmtx'.
+class HorizontalMetricsTable : public Table,
+                               public RefCounted<HorizontalMetricsTable> {
+ public:
+  // Builder for a Horizontal Metrics Table - 'hmtx'.
+  class Builder : public TableBasedTableBuilder, public RefCounted<Builder> {
+   public:
+    // Constructor scope altered to public because C++ does not allow base
+    // class to instantiate derived class with protected constructors.
+    Builder(Header* header, WritableFontData* data);
+    Builder(Header* header, ReadableFontData* data);
+    virtual ~Builder();
+
+    virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+    static CALLER_ATTACH Builder* CreateBuilder(Header* header,
+                                                WritableFontData* data);
+
+    void SetNumberOfHMetrics(int32_t num_hmetrics);
+    void SetNumGlyphs(int32_t num_glyphs);
+
+   private:
+    int32_t num_hmetrics_;
+    int32_t num_glyphs_;
+  };
+
+  virtual ~HorizontalMetricsTable();
+  int32_t NumberOfHMetrics();
+  int32_t NumberOfLSBs();
+  int32_t HMetricAdvanceWidth(int32_t entry);
+  int32_t HMetricLSB(int32_t entry);
+  int32_t LsbTableEntry(int32_t entry);
+  int32_t AdvanceWidth(int32_t glyph_id);
+  int32_t LeftSideBearing(int32_t glyph_id);
+
+ private:
+  struct Offset {
+    enum {
+      // hMetrics
+      kHMetricsStart = 0,
+      kHMetricsSize = 4,
+
+      // Offset within an hMetric
+      kHMetricsAdvanceWidth = 0,
+      kHMetricsLeftSideBearing = 2,
+
+      kLeftSideBearingSize = 2
+    };
+  };
+
+  HorizontalMetricsTable(Header* header,
+                         ReadableFontData* data,
+                         int32_t num_hmetrics,
+                         int32_t num_glyphs);
+
+  int32_t num_hmetrics_;
+  int32_t num_glyphs_;
+};
+typedef Ptr<HorizontalMetricsTable> HorizontalMetricsTablePtr;
+typedef Ptr<HorizontalMetricsTable::Builder> HorizontalMetricsTableBuilderPtr;
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_HORIZONTAL_METRICS_TABLE_H_
diff --git a/sfntly/table/core/maximum_profile_table.cc b/sfntly/table/core/maximum_profile_table.cc
new file mode 100644
index 0000000..a8ac3bc
--- /dev/null
+++ b/sfntly/table/core/maximum_profile_table.cc
@@ -0,0 +1,240 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/table/core/maximum_profile_table.h"
+
+namespace sfntly {
+/******************************************************************************
+ * MaximumProfileTable class
+ ******************************************************************************/
+MaximumProfileTable::~MaximumProfileTable() {}
+
+int32_t MaximumProfileTable::TableVersion() {
+  return data_->ReadFixed(Offset::kVersion);
+}
+
+int32_t MaximumProfileTable::NumGlyphs() {
+  return data_->ReadUShort(Offset::kNumGlyphs);
+}
+
+int32_t MaximumProfileTable::MaxPoints() {
+  return data_->ReadUShort(Offset::kMaxPoints);
+}
+
+int32_t MaximumProfileTable::MaxContours() {
+  return data_->ReadUShort(Offset::kMaxContours);
+}
+
+int32_t MaximumProfileTable::MaxCompositePoints() {
+  return data_->ReadUShort(Offset::kMaxCompositePoints);
+}
+
+int32_t MaximumProfileTable::MaxCompositeContours() {
+  return data_->ReadUShort(Offset::kMaxCompositeContours);
+}
+
+int32_t MaximumProfileTable::MaxZones() {
+  return data_->ReadUShort(Offset::kMaxZones);
+}
+
+int32_t MaximumProfileTable::MaxTwilightPoints() {
+  return data_->ReadUShort(Offset::kMaxTwilightPoints);
+}
+
+int32_t MaximumProfileTable::MaxStorage() {
+  return data_->ReadUShort(Offset::kMaxStorage);
+}
+
+int32_t MaximumProfileTable::MaxFunctionDefs() {
+  return data_->ReadUShort(Offset::kMaxFunctionDefs);
+}
+
+int32_t MaximumProfileTable::MaxStackElements() {
+  return data_->ReadUShort(Offset::kMaxStackElements);
+}
+
+int32_t MaximumProfileTable::MaxSizeOfInstructions() {
+  return data_->ReadUShort(Offset::kMaxSizeOfInstructions);
+}
+
+int32_t MaximumProfileTable::MaxComponentElements() {
+  return data_->ReadUShort(Offset::kMaxComponentElements);
+}
+
+int32_t MaximumProfileTable::MaxComponentDepth() {
+  return data_->ReadUShort(Offset::kMaxComponentDepth);
+}
+
+MaximumProfileTable::MaximumProfileTable(Header* header,
+                                         ReadableFontData* data)
+    : Table(header, data) {
+}
+
+/******************************************************************************
+ * MaximumProfileTable::Builder class
+ ******************************************************************************/
+MaximumProfileTable::Builder::Builder(Header* header, WritableFontData* data)
+    : TableBasedTableBuilder(header, data) {
+}
+
+MaximumProfileTable::Builder::Builder(Header* header, ReadableFontData* data)
+    : TableBasedTableBuilder(header, data) {
+}
+
+MaximumProfileTable::Builder::~Builder() {}
+
+CALLER_ATTACH FontDataTable*
+    MaximumProfileTable::Builder::SubBuildTable(ReadableFontData* data) {
+  FontDataTablePtr table = new MaximumProfileTable(header(), data);
+  return table.Detach();
+}
+
+CALLER_ATTACH MaximumProfileTable::Builder*
+    MaximumProfileTable::Builder::CreateBuilder(Header* header,
+                                                WritableFontData* data) {
+  Ptr<MaximumProfileTable::Builder> builder;
+  builder = new MaximumProfileTable::Builder(header, data);
+  return builder.Detach();
+}
+
+int32_t MaximumProfileTable::Builder::TableVersion() {
+  return InternalReadData()->ReadUShort(Offset::kVersion);
+}
+
+void MaximumProfileTable::Builder::SetTableVersion(int32_t version) {
+  InternalWriteData()->WriteUShort(Offset::kVersion, version);
+}
+
+int32_t MaximumProfileTable::Builder::NumGlyphs() {
+  return InternalReadData()->ReadUShort(Offset::kNumGlyphs);
+}
+
+void MaximumProfileTable::Builder::SetNumGlyphs(int32_t num_glyphs) {
+  InternalWriteData()->WriteUShort(Offset::kNumGlyphs, num_glyphs);
+}
+
+int32_t MaximumProfileTable::Builder::MaxPoints() {
+  return InternalReadData()->ReadUShort(Offset::kMaxPoints);
+}
+
+void MaximumProfileTable::Builder::SetMaxPoints(int32_t max_points) {
+  InternalWriteData()->WriteUShort(Offset::kMaxPoints, max_points);
+}
+
+int32_t MaximumProfileTable::Builder::MaxContours() {
+  return InternalReadData()->ReadUShort(Offset::kMaxContours);
+}
+
+void MaximumProfileTable::Builder::SetMaxContours(int32_t max_contours) {
+  InternalWriteData()->WriteUShort(Offset::kMaxContours, max_contours);
+}
+
+int32_t MaximumProfileTable::Builder::MaxCompositePoints() {
+  return InternalReadData()->ReadUShort(Offset::kMaxCompositePoints);
+}
+
+void MaximumProfileTable::Builder::SetMaxCompositePoints(
+    int32_t max_composite_points) {
+  InternalWriteData()->WriteUShort(Offset::kMaxCompositePoints,
+                                   max_composite_points);
+}
+
+int32_t MaximumProfileTable::Builder::MaxCompositeContours() {
+  return InternalReadData()->ReadUShort(Offset::kMaxCompositeContours);
+}
+
+void MaximumProfileTable::Builder::SetMaxCompositeContours(
+    int32_t max_composite_contours) {
+  InternalWriteData()->WriteUShort(Offset::kMaxCompositeContours,
+      max_composite_contours);
+}
+
+int32_t MaximumProfileTable::Builder::MaxZones() {
+  return InternalReadData()->ReadUShort(Offset::kMaxZones);
+}
+
+void MaximumProfileTable::Builder::SetMaxZones(int32_t max_zones) {
+  InternalWriteData()->WriteUShort(Offset::kMaxZones, max_zones);
+}
+
+int32_t MaximumProfileTable::Builder::MaxTwilightPoints() {
+  return InternalReadData()->ReadUShort(Offset::kMaxTwilightPoints);
+}
+
+void MaximumProfileTable::Builder::SetMaxTwilightPoints(
+    int32_t max_twilight_points) {
+  InternalWriteData()->WriteUShort(Offset::kMaxTwilightPoints,
+                                   max_twilight_points);
+}
+
+int32_t MaximumProfileTable::Builder::MaxStorage() {
+  return InternalReadData()->ReadUShort(Offset::kMaxStorage);
+}
+
+void MaximumProfileTable::Builder::SetMaxStorage(int32_t max_storage) {
+  InternalWriteData()->WriteUShort(Offset::kMaxStorage, max_storage);
+}
+
+int32_t MaximumProfileTable::Builder::MaxFunctionDefs() {
+  return InternalReadData()->ReadUShort(Offset::kMaxFunctionDefs);
+}
+
+void MaximumProfileTable::Builder::SetMaxFunctionDefs(
+    int32_t max_function_defs) {
+  InternalWriteData()->WriteUShort(Offset::kMaxFunctionDefs, max_function_defs);
+}
+
+int32_t MaximumProfileTable::Builder::MaxStackElements() {
+  return InternalReadData()->ReadUShort(Offset::kMaxStackElements);
+}
+
+void MaximumProfileTable::Builder::SetMaxStackElements(
+    int32_t max_stack_elements) {
+  InternalWriteData()->WriteUShort(Offset::kMaxStackElements,
+                                   max_stack_elements);
+}
+
+int32_t MaximumProfileTable::Builder::MaxSizeOfInstructions() {
+  return InternalReadData()->ReadUShort(Offset::kMaxSizeOfInstructions);
+}
+
+void MaximumProfileTable::Builder::SetMaxSizeOfInstructions(
+    int32_t max_size_of_instructions) {
+  InternalWriteData()->WriteUShort(Offset::kMaxSizeOfInstructions,
+                                   max_size_of_instructions);
+}
+
+int32_t MaximumProfileTable::Builder::MaxComponentElements() {
+  return InternalReadData()->ReadUShort(Offset::kMaxComponentElements);
+}
+
+void MaximumProfileTable::Builder::SetMaxComponentElements(
+    int32_t max_component_elements) {
+  InternalWriteData()->WriteUShort(Offset::kMaxComponentElements,
+                                   max_component_elements);
+}
+
+int32_t MaximumProfileTable::Builder::MaxComponentDepth() {
+  return InternalReadData()->ReadUShort(Offset::kMaxComponentDepth);
+}
+
+void MaximumProfileTable::Builder::SetMaxComponentDepth(
+    int32_t max_component_depth) {
+  InternalWriteData()->WriteUShort(Offset::kMaxComponentDepth,
+                                   max_component_depth);
+}
+
+}  // namespace sfntly
diff --git a/sfntly/table/core/maximum_profile_table.h b/sfntly/table/core/maximum_profile_table.h
new file mode 100644
index 0000000..e7c5abb
--- /dev/null
+++ b/sfntly/table/core/maximum_profile_table.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_MAXIMUM_PROFILE_TABLE_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_MAXIMUM_PROFILE_TABLE_H_
+
+#include "sfntly/port/refcount.h"
+#include "sfntly/table/table.h"
+#include "sfntly/table/table_based_table_builder.h"
+
+namespace sfntly {
+
+// A Maximum Profile table - 'maxp'.
+class MaximumProfileTable : public Table,
+                            public RefCounted<MaximumProfileTable> {
+ public:
+  // Builder for a Maximum Profile table - 'maxp'.
+  class Builder : public TableBasedTableBuilder, public RefCounted<Builder> {
+   public:
+    // Constructor scope altered to public because C++ does not allow base
+    // class to instantiate derived class with protected constructors.
+    Builder(Header* header, WritableFontData* data);
+    Builder(Header* header, ReadableFontData* data);
+    virtual ~Builder();
+
+    virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+    static CALLER_ATTACH Builder* CreateBuilder(Header* header,
+                                                WritableFontData* data);
+
+    int32_t TableVersion();
+    void SetTableVersion(int32_t version);
+    int32_t NumGlyphs();
+    void SetNumGlyphs(int32_t num_glyphs);
+    int32_t MaxPoints();
+    void SetMaxPoints(int32_t max_points);
+    int32_t MaxContours();
+    void SetMaxContours(int32_t max_contours);
+    int32_t MaxCompositePoints();
+    void SetMaxCompositePoints(int32_t max_composite_points);
+    int32_t MaxCompositeContours();
+    void SetMaxCompositeContours(int32_t max_composite_contours);
+    int32_t MaxZones();
+    void SetMaxZones(int32_t max_zones);
+    int32_t MaxTwilightPoints();
+    void SetMaxTwilightPoints(int32_t max_twilight_points);
+    int32_t MaxStorage();
+    void SetMaxStorage(int32_t max_storage);
+    int32_t MaxFunctionDefs();
+    void SetMaxFunctionDefs(int32_t max_function_defs);
+    int32_t MaxStackElements();
+    void SetMaxStackElements(int32_t max_stack_elements);
+    int32_t MaxSizeOfInstructions();
+    void SetMaxSizeOfInstructions(int32_t max_size_of_instructions);
+    int32_t MaxComponentElements();
+    void SetMaxComponentElements(int32_t max_component_elements);
+    int32_t MaxComponentDepth();
+    void SetMaxComponentDepth(int32_t max_component_depth);
+  };
+
+  virtual ~MaximumProfileTable();
+  int32_t TableVersion();
+  int32_t NumGlyphs();
+  int32_t MaxPoints();
+  int32_t MaxContours();
+  int32_t MaxCompositePoints();
+  int32_t MaxCompositeContours();
+  int32_t MaxZones();
+  int32_t MaxTwilightPoints();
+  int32_t MaxStorage();
+  int32_t MaxFunctionDefs();
+  int32_t MaxStackElements();
+  int32_t MaxSizeOfInstructions();
+  int32_t MaxComponentElements();
+  int32_t MaxComponentDepth();
+
+ private:
+  struct Offset {
+    enum {
+      // version 0.5 and 1.0
+      kVersion = 0,
+      kNumGlyphs = 4,
+
+      // version 1.0
+      kMaxPoints = 6,
+      kMaxContours = 8,
+      kMaxCompositePoints = 10,
+      kMaxCompositeContours = 12,
+      kMaxZones = 14,
+      kMaxTwilightPoints = 16,
+      kMaxStorage = 18,
+      kMaxFunctionDefs = 20,
+      kMaxInstructionDefs = 22,
+      kMaxStackElements = 24,
+      kMaxSizeOfInstructions = 26,
+      kMaxComponentElements = 28,
+      kMaxComponentDepth = 30,
+    };
+  };
+
+  MaximumProfileTable(Header* header, ReadableFontData* data);
+};
+typedef Ptr<MaximumProfileTable> MaximumProfileTablePtr;
+typedef Ptr<MaximumProfileTable::Builder> MaximumProfileTableBuilderPtr;
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_MAXIMUM_PROFILE_TABLE_H_
diff --git a/sfntly/table/core/name_table.cc b/sfntly/table/core/name_table.cc
new file mode 100644
index 0000000..8d2f64f
--- /dev/null
+++ b/sfntly/table/core/name_table.cc
@@ -0,0 +1,723 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/table/core/name_table.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <unicode/unistr.h>
+
+#include "sfntly/font.h"
+#include "sfntly/port/exception_type.h"
+
+namespace sfntly {
+/******************************************************************************
+ * NameTable::NameEntryId class
+ ******************************************************************************/
+NameTable::NameEntryId::NameEntryId()
+    : platform_id_(0),
+      encoding_id_(0),
+      language_id_(0),
+      name_id_(0) {
+}
+
+NameTable::NameEntryId::NameEntryId(int32_t platform_id,
+                                    int32_t encoding_id,
+                                    int32_t language_id,
+                                    int32_t name_id)
+    : platform_id_(platform_id),
+      encoding_id_(encoding_id),
+      language_id_(language_id),
+      name_id_(name_id) {
+}
+
+NameTable::NameEntryId::NameEntryId(const NameTable::NameEntryId& rhs) {
+  *this = rhs;
+}
+
+const NameTable::NameEntryId&
+    NameTable::NameEntryId::operator=(const NameTable::NameEntryId& rhs) const {
+  platform_id_ = rhs.platform_id_;
+  encoding_id_ = rhs.encoding_id_;
+  language_id_ = rhs.language_id_;
+  name_id_ = rhs.name_id_;
+  return *this;
+}
+
+bool NameTable::NameEntryId::operator==(const NameEntryId& rhs) const {
+  return platform_id_ == rhs.platform_id_ &&
+         encoding_id_ == rhs.encoding_id_ &&
+         language_id_ == rhs.language_id_ &&
+         name_id_ == rhs.name_id_;
+}
+
+bool NameTable::NameEntryId::operator<(const NameEntryId& rhs) const {
+  if (platform_id_ != rhs.platform_id_) return platform_id_ < rhs.platform_id_;
+  if (encoding_id_ != rhs.encoding_id_) return encoding_id_ < rhs.encoding_id_;
+  if (language_id_ != rhs.language_id_) return language_id_ < rhs.language_id_;
+  return name_id_ < rhs.name_id_;
+}
+
+/******************************************************************************
+ * NameTable::NameEntry class
+ ******************************************************************************/
+NameTable::NameEntry::NameEntry() {
+  Init(0, 0, 0, 0, NULL);
+}
+
+NameTable::NameEntry::NameEntry(const NameEntryId& name_entry_id,
+                                const ByteVector& name_bytes) {
+  Init(name_entry_id.platform_id(),
+       name_entry_id.encoding_id(),
+       name_entry_id.language_id(),
+       name_entry_id.name_id(),
+       &name_bytes);
+}
+
+NameTable::NameEntry::NameEntry(int32_t platform_id,
+                                int32_t encoding_id,
+                                int32_t language_id,
+                                int32_t name_id,
+                                const ByteVector& name_bytes) {
+  Init(platform_id, encoding_id, language_id, name_id, &name_bytes);
+}
+
+NameTable::NameEntry::~NameEntry() {}
+
+ByteVector* NameTable::NameEntry::NameAsBytes() {
+  return &name_bytes_;
+}
+
+int32_t NameTable::NameEntry::NameBytesLength() {
+  return name_bytes_.size();
+}
+
+UChar* NameTable::NameEntry::Name() {
+  return NameTable::ConvertFromNameBytes(&name_bytes_,
+                                         platform_id(),
+                                         encoding_id());
+}
+
+bool NameTable::NameEntry::operator==(const NameEntry& rhs) const {
+  return (name_entry_id_ == rhs.name_entry_id_ &&
+          name_bytes_ == rhs.name_bytes_);
+}
+
+void NameTable::NameEntry::Init(int32_t platform_id,
+                                int32_t encoding_id,
+                                int32_t language_id,
+                                int32_t name_id,
+                                const ByteVector* name_bytes) {
+  name_entry_id_ = NameEntryId(platform_id, encoding_id, language_id, name_id);
+  if (name_bytes) {
+    name_bytes_ = *name_bytes;
+  } else {
+    name_bytes_.clear();
+  }
+}
+
+/******************************************************************************
+ * NameTable::NameEntryBuilder class
+ ******************************************************************************/
+NameTable::NameEntryBuilder::NameEntryBuilder() {
+  Init(0, 0, 0, 0, NULL);
+}
+
+NameTable::NameEntryBuilder::NameEntryBuilder(const NameEntryId& name_entry_id,
+                                              const ByteVector& name_bytes) {
+  Init(name_entry_id.platform_id(),
+       name_entry_id.encoding_id(),
+       name_entry_id.language_id(),
+       name_entry_id.name_id(),
+       &name_bytes);
+}
+
+NameTable::NameEntryBuilder::NameEntryBuilder(
+    const NameEntryId& name_entry_id) {
+  Init(name_entry_id.platform_id(),
+       name_entry_id.encoding_id(),
+       name_entry_id.language_id(),
+       name_entry_id.name_id(),
+       NULL);
+}
+
+NameTable::NameEntryBuilder::NameEntryBuilder(NameEntry* b) {
+  Init(b->platform_id(),
+       b->encoding_id(),
+       b->language_id(),
+       b->name_id(),
+       b->NameAsBytes());
+}
+
+NameTable::NameEntryBuilder::~NameEntryBuilder() {}
+
+void NameTable::NameEntryBuilder::SetName(const UChar* name) {
+  if (name == NULL) {
+    name_entry_->name_bytes_.clear();
+    return;
+  }
+  NameTable::ConvertToNameBytes(name,
+                                name_entry_->platform_id(),
+                                name_entry_->encoding_id(),
+                                &name_entry_->name_bytes_);
+}
+
+void NameTable::NameEntryBuilder::SetName(const ByteVector& name_bytes) {
+  name_entry_->name_bytes_.clear();
+  std::copy(name_bytes.begin(),
+            name_bytes.end(),
+            name_entry_->name_bytes_.begin());
+}
+
+void NameTable::NameEntryBuilder::SetName(const ByteVector& name_bytes,
+                                          int32_t offset,
+                                          int32_t length) {
+  name_entry_->name_bytes_.clear();
+  std::copy(name_bytes.begin() + offset,
+            name_bytes.begin() + offset + length,
+            name_entry_->name_bytes_.begin());
+}
+
+void NameTable::NameEntryBuilder::Init(int32_t platform_id,
+                                       int32_t encoding_id,
+                                       int32_t language_id,
+                                       int32_t name_id,
+                                       const ByteVector* name_bytes) {
+  name_entry_ = new NameEntry();
+  name_entry_->Init(platform_id, encoding_id, language_id, name_id, name_bytes);
+}
+
+/******************************************************************************
+ * NameTable::NameEntryFilterInPlace class (C++ port only)
+ ******************************************************************************/
+NameTable::NameEntryFilterInPlace::NameEntryFilterInPlace(int32_t platform_id,
+                                                          int32_t encoding_id,
+                                                          int32_t language_id,
+                                                          int32_t name_id)
+    : platform_id_(platform_id),
+      encoding_id_(encoding_id),
+      language_id_(language_id),
+      name_id_(name_id) {
+}
+
+bool NameTable::NameEntryFilterInPlace::Accept(int32_t platform_id,
+                                               int32_t encoding_id,
+                                               int32_t language_id,
+                                               int32_t name_id) {
+  return (platform_id_ == platform_id &&
+          encoding_id_ == encoding_id &&
+          language_id_ == language_id &&
+          name_id_ == name_id);
+}
+
+/******************************************************************************
+ * NameTable::NameEntryIterator class
+ ******************************************************************************/
+NameTable::NameEntryIterator::NameEntryIterator(NameTable* table)
+    : RefIterator<NameEntry, NameTable>(table),
+      name_index_(0),
+      filter_(NULL) {
+}
+
+NameTable::NameEntryIterator::NameEntryIterator(NameTable* table,
+                                                NameEntryFilter* filter)
+    : RefIterator<NameEntry, NameTable>(table),
+      name_index_(0),
+      filter_(filter) {
+}
+
+bool NameTable::NameEntryIterator::HasNext() {
+  if (!filter_) {
+    if (name_index_ < container()->NameCount()) {
+      return true;
+    }
+    return false;
+  }
+  for (; name_index_ < container()->NameCount(); ++name_index_) {
+    if (filter_->Accept(container()->PlatformId(name_index_),
+                        container()->EncodingId(name_index_),
+                        container()->LanguageId(name_index_),
+                        container()->NameId(name_index_))) {
+      return true;
+    }
+  }
+  return false;
+}
+
+CALLER_ATTACH NameTable::NameEntry* NameTable::NameEntryIterator::Next() {
+  if (!HasNext())
+    return NULL;
+  return container()->GetNameEntry(name_index_++);
+}
+
+/******************************************************************************
+ * NameTable::Builder class
+ ******************************************************************************/
+NameTable::Builder::Builder(Header* header, WritableFontData* data)
+    : SubTableContainerTable::Builder(header, data) {
+}
+
+NameTable::Builder::Builder(Header* header, ReadableFontData* data)
+    : SubTableContainerTable::Builder(header, data) {
+}
+
+CALLER_ATTACH NameTable::Builder*
+    NameTable::Builder::CreateBuilder(Header* header,
+                                      WritableFontData* data) {
+  Ptr<NameTable::Builder> builder;
+  builder = new NameTable::Builder(header, data);
+  return builder.Detach();
+}
+
+void NameTable::Builder::RevertNames() {
+  name_entry_map_.clear();
+  set_model_changed(false);
+}
+
+int32_t NameTable::Builder::BuilderCount() {
+  GetNameBuilders();  // Ensure name_entry_map_ is built.
+  return (int32_t)name_entry_map_.size();
+}
+
+bool NameTable::Builder::Has(int32_t platform_id,
+                             int32_t encoding_id,
+                             int32_t language_id,
+                             int32_t name_id) {
+  NameEntryId probe(platform_id, encoding_id, language_id, name_id);
+  GetNameBuilders();  // Ensure name_entry_map_ is built.
+  return (name_entry_map_.find(probe) != name_entry_map_.end());
+}
+
+CALLER_ATTACH NameTable::NameEntryBuilder*
+    NameTable::Builder::NameBuilder(int32_t platform_id,
+                                    int32_t encoding_id,
+                                    int32_t language_id,
+                                    int32_t name_id) {
+  NameEntryId probe(platform_id, encoding_id, language_id, name_id);
+  NameEntryBuilderMap builders;
+  GetNameBuilders();  // Ensure name_entry_map_ is built.
+  if (name_entry_map_.find(probe) != name_entry_map_.end()) {
+    return name_entry_map_[probe];
+  }
+  NameEntryBuilderPtr builder = new NameEntryBuilder(probe);
+  name_entry_map_[probe] = builder;
+  return builder.Detach();
+}
+
+bool NameTable::Builder::Remove(int32_t platform_id,
+                                int32_t encoding_id,
+                                int32_t language_id,
+                                int32_t name_id) {
+  NameEntryId probe(platform_id, encoding_id, language_id, name_id);
+  GetNameBuilders();  // Ensure name_entry_map_ is built.
+  NameEntryBuilderMap::iterator position = name_entry_map_.find(probe);
+  if (position != name_entry_map_.end()) {
+    name_entry_map_.erase(position);
+    return true;
+  }
+  return false;
+}
+
+CALLER_ATTACH FontDataTable*
+    NameTable::Builder::SubBuildTable(ReadableFontData* data) {
+  FontDataTablePtr table = new NameTable(header(), data);
+  return table.Detach();
+}
+
+void NameTable::Builder::SubDataSet() {
+  name_entry_map_.clear();
+  set_model_changed(false);
+}
+
+int32_t NameTable::Builder::SubDataSizeToSerialize() {
+  if (name_entry_map_.empty()) {
+    return 0;
+  }
+
+  int32_t size = NameTable::Offset::kNameRecordStart +
+                 name_entry_map_.size() * NameTable::Offset::kNameRecordSize;
+  for (NameEntryBuilderMap::iterator b = name_entry_map_.begin(),
+                                     end = name_entry_map_.end();
+                                     b != end; ++b) {
+    NameEntryBuilderPtr p = b->second;
+    NameEntry* entry = p->name_entry();
+    size += entry->NameBytesLength();
+  }
+  return size;
+}
+
+bool NameTable::Builder::SubReadyToSerialize() {
+  return !name_entry_map_.empty();
+}
+
+int32_t NameTable::Builder::SubSerialize(WritableFontData* new_data) {
+  int32_t string_table_start_offset =
+      NameTable::Offset::kNameRecordStart +
+      name_entry_map_.size() * NameTable::Offset::kNameRecordSize;
+
+  // Header
+  new_data->WriteUShort(NameTable::Offset::kFormat, 0);
+  new_data->WriteUShort(NameTable::Offset::kCount, name_entry_map_.size());
+  new_data->WriteUShort(NameTable::Offset::kStringOffset,
+                        string_table_start_offset);
+  int32_t name_record_offset = NameTable::Offset::kNameRecordStart;
+  int32_t string_offset = 0;
+  // Note: we offered operator< in NameEntryId, which will be used by std::less,
+  //       and therefore our map will act like TreeMap in Java to provide
+  //       sorted key set.
+  for (NameEntryBuilderMap::iterator b = name_entry_map_.begin(),
+                                     end = name_entry_map_.end();
+                                     b != end; ++b) {
+    new_data->WriteUShort(
+        name_record_offset + NameTable::Offset::kNameRecordPlatformId,
+        b->first.platform_id());
+    new_data->WriteUShort(
+        name_record_offset + NameTable::Offset::kNameRecordEncodingId,
+        b->first.encoding_id());
+    new_data->WriteUShort(
+        name_record_offset + NameTable::Offset::kNameRecordLanguageId,
+        b->first.language_id());
+    new_data->WriteUShort(
+        name_record_offset + NameTable::Offset::kNameRecordNameId,
+        b->first.name_id());
+    NameEntry* builder_entry = b->second->name_entry();
+    new_data->WriteUShort(
+        name_record_offset + NameTable::Offset::kNameRecordStringLength,
+        builder_entry->NameBytesLength());
+    new_data->WriteUShort(
+        name_record_offset + NameTable::Offset::kNameRecordStringOffset,
+        string_offset);
+    name_record_offset += NameTable::Offset::kNameRecordSize;
+    string_offset += new_data->WriteBytes(
+        string_offset + string_table_start_offset,
+        builder_entry->NameAsBytes());
+  }
+
+  return string_offset + string_table_start_offset;
+}
+
+void NameTable::Builder::Initialize(ReadableFontData* data) {
+  if (data) {
+    NameTablePtr table = new NameTable(header(), data);
+    Ptr<NameEntryIterator> name_iter;
+    name_iter.Attach(table->Iterator());
+    while (name_iter->HasNext()) {
+      NameEntryPtr name_entry;
+      name_entry.Attach(name_iter->Next());
+      NameEntryBuilderPtr name_entry_builder = new NameEntryBuilder(name_entry);
+      NameEntry* builder_entry = name_entry_builder->name_entry();
+      NameEntryId probe = builder_entry->name_entry_id();
+      name_entry_map_[probe] = name_entry_builder;
+    }
+  }
+}
+
+NameTable::NameEntryBuilderMap* NameTable::Builder::GetNameBuilders() {
+  if (name_entry_map_.empty()) {
+    Initialize(InternalReadData());
+  }
+  set_model_changed();
+  return &name_entry_map_;
+}
+
+/******************************************************************************
+ * NameTable class
+ ******************************************************************************/
+NameTable::~NameTable() {}
+
+int32_t NameTable::Format() {
+  return data_->ReadUShort(Offset::kFormat);
+}
+
+int32_t NameTable::NameCount() {
+  return data_->ReadUShort(Offset::kCount);
+}
+
+int32_t NameTable::PlatformId(int32_t index) {
+  return data_->ReadUShort(Offset::kNameRecordPlatformId +
+                           OffsetForNameRecord(index));
+}
+
+int32_t NameTable::EncodingId(int32_t index) {
+  return data_->ReadUShort(Offset::kNameRecordEncodingId +
+                           OffsetForNameRecord(index));
+}
+
+int32_t NameTable::LanguageId(int32_t index) {
+  return data_->ReadUShort(Offset::kNameRecordLanguageId +
+                           OffsetForNameRecord(index));
+}
+
+int32_t NameTable::NameId(int32_t index) {
+  return data_->ReadUShort(Offset::kNameRecordNameId +
+                           OffsetForNameRecord(index));
+}
+
+void NameTable::NameAsBytes(int32_t index, ByteVector* b) {
+  assert(b);
+  int32_t length = NameLength(index);
+  b->clear();
+  b->resize(length);
+  if (length > 0) {
+    data_->ReadBytes(NameOffset(index), &((*b)[0]), 0, length);
+  }
+}
+
+void NameTable::NameAsBytes(int32_t platform_id,
+                            int32_t encoding_id,
+                            int32_t language_id,
+                            int32_t name_id,
+                            ByteVector* b) {
+  assert(b);
+  NameEntryPtr entry;
+  entry.Attach(GetNameEntry(platform_id, encoding_id, language_id, name_id));
+  if (entry) {
+    ByteVector* name = entry->NameAsBytes();
+    std::copy(name->begin(), name->end(), b->begin());
+  }
+}
+
+UChar* NameTable::Name(int32_t index) {
+  ByteVector b;
+  NameAsBytes(index, &b);
+  return ConvertFromNameBytes(&b, PlatformId(index), EncodingId(index));
+}
+
+UChar* NameTable::Name(int32_t platform_id,
+                       int32_t encoding_id,
+                       int32_t language_id,
+                       int32_t name_id) {
+  NameEntryPtr entry;
+  entry.Attach(GetNameEntry(platform_id, encoding_id, language_id, name_id));
+  if (entry) {
+    return entry->Name();
+  }
+  return NULL;
+}
+
+CALLER_ATTACH NameTable::NameEntry* NameTable::GetNameEntry(int32_t index) {
+  ByteVector b;
+  NameAsBytes(index, &b);
+  NameEntryPtr instance = new NameEntry(PlatformId(index),
+                                        EncodingId(index),
+                                        LanguageId(index),
+                                        NameId(index), b);
+  return instance.Detach();
+}
+
+CALLER_ATTACH NameTable::NameEntry* NameTable::GetNameEntry(int32_t platform_id,
+                                                            int32_t encoding_id,
+                                                            int32_t language_id,
+                                                            int32_t name_id) {
+  NameTable::NameEntryFilterInPlace
+      filter(platform_id, encoding_id, language_id, name_id);
+  Ptr<NameTable::NameEntryIterator> name_entry_iter;
+  name_entry_iter.Attach(Iterator(&filter));
+  NameEntryPtr result;
+  if (name_entry_iter->HasNext()) {
+    result = name_entry_iter->Next();
+  }
+  return result;
+}
+
+CALLER_ATTACH NameTable::NameEntryIterator* NameTable::Iterator() {
+  Ptr<NameEntryIterator> output = new NameTable::NameEntryIterator(this);
+  return output.Detach();
+}
+
+CALLER_ATTACH
+NameTable::NameEntryIterator* NameTable::Iterator(NameEntryFilter* filter) {
+  Ptr<NameEntryIterator> output =
+      new NameTable::NameEntryIterator(this, filter);
+  return output.Detach();
+}
+
+NameTable::NameTable(Header* header, ReadableFontData* data)
+    : SubTableContainerTable(header, data) {}
+
+int32_t NameTable::StringOffset() {
+  return data_->ReadUShort(Offset::kStringOffset);
+}
+
+int32_t NameTable::OffsetForNameRecord(int32_t index) {
+  return Offset::kNameRecordStart + index * Offset::kNameRecordSize;
+}
+
+int32_t NameTable::NameLength(int32_t index) {
+  return data_->ReadUShort(Offset::kNameRecordStringLength +
+                           OffsetForNameRecord(index));
+}
+
+int32_t NameTable::NameOffset(int32_t index) {
+  return data_->ReadUShort(Offset::kNameRecordStringOffset +
+                           OffsetForNameRecord(index)) + StringOffset();
+}
+
+const char* NameTable::GetEncodingName(int32_t platform_id,
+                                       int32_t encoding_id) {
+  switch (platform_id) {
+    case PlatformId::kUnicode:
+      return "UTF-16BE";
+    case PlatformId::kMacintosh:
+      switch (encoding_id) {
+        case MacintoshEncodingId::kRoman:
+          return "MacRoman";
+        case MacintoshEncodingId::kJapanese:
+          return "Shift-JIS";
+        case MacintoshEncodingId::kChineseTraditional:
+          return "Big5";
+        case MacintoshEncodingId::kKorean:
+          return "EUC-KR";
+        case MacintoshEncodingId::kArabic:
+          return "MacArabic";
+        case MacintoshEncodingId::kHebrew:
+          return "MacHebrew";
+        case MacintoshEncodingId::kGreek:
+          return "MacGreek";
+        case MacintoshEncodingId::kRussian:
+          return "MacCyrillic";
+        case MacintoshEncodingId::kRSymbol:
+          return "MacSymbol";
+        case MacintoshEncodingId::kThai:
+          return "MacThai";
+        case MacintoshEncodingId::kChineseSimplified:
+          return "EUC-CN";
+        default:  // Note: unknown/unconfirmed cases are not ported.
+          break;
+      }
+      break;
+    case PlatformId::kISO:
+      break;
+    case PlatformId::kWindows:
+      switch (encoding_id) {
+        case WindowsEncodingId::kSymbol:
+        case WindowsEncodingId::kUnicodeUCS2:
+          return "UTF-16BE";
+        case WindowsEncodingId::kShiftJIS:
+          return "windows-933";
+        case WindowsEncodingId::kPRC:
+          return "windows-936";
+        case WindowsEncodingId::kBig5:
+          return "windows-950";
+        case WindowsEncodingId::kWansung:
+          return "windows-949";
+        case WindowsEncodingId::kJohab:
+          return "ms1361";
+        case WindowsEncodingId::kUnicodeUCS4:
+          return "UCS-4";
+      }
+      break;
+    case PlatformId::kCustom:
+      break;
+    default:
+      break;
+  }
+  return NULL;
+}
+
+UConverter* NameTable::GetCharset(int32_t platform_id, int32_t encoding_id) {
+  UErrorCode error_code = U_ZERO_ERROR;
+  UConverter* conv = ucnv_open(GetEncodingName(platform_id, encoding_id),
+                               &error_code);
+  if (U_SUCCESS(error_code)) {
+    return conv;
+  }
+
+  if (conv) {
+    ucnv_close(conv);
+  }
+  return NULL;
+}
+
+void NameTable::ConvertToNameBytes(const UChar* name,
+                                   int32_t platform_id,
+                                   int32_t encoding_id,
+                                   ByteVector* b) {
+  assert(b);
+  assert(name);
+  b->clear();
+  UConverter* cs = GetCharset(platform_id, encoding_id);
+  if (cs == NULL) {
+    return;
+  }
+
+  // Preflight to get buffer size.
+  UErrorCode error_code = U_ZERO_ERROR;
+  int32_t length = ucnv_fromUChars(cs, NULL, 0, name, -1, &error_code);
+  b->resize(length + 4);  // The longest termination "\0" is 4 bytes.
+  memset(&((*b)[0]), 0, length + 4);
+  error_code = U_ZERO_ERROR;
+  ucnv_fromUChars(cs,
+                  reinterpret_cast<char*>(&((*b)[0])),
+                  length + 4,
+                  name,
+                  -1,
+                  &error_code);
+  if (!U_SUCCESS(error_code)) {
+    b->clear();
+  }
+  ucnv_close(cs);
+}
+
+UChar* NameTable::ConvertFromNameBytes(ByteVector* name_bytes,
+                                       int32_t platform_id,
+                                       int32_t encoding_id) {
+  if (name_bytes == NULL || name_bytes->size() == 0) {
+    return NULL;
+  }
+  UConverter* cs = GetCharset(platform_id, encoding_id);
+  UErrorCode error_code = U_ZERO_ERROR;
+  if (cs == NULL) {
+    char buffer[11] = {0};
+#if defined (WIN32)
+    _itoa_s(platform_id, buffer, 16);
+#else
+    snprintf(buffer, sizeof(buffer), "%x", platform_id);
+#endif
+    UChar* result = new UChar[12];
+    memset(result, 0, sizeof(UChar) * 12);
+    cs = ucnv_open("utf-8", &error_code);
+    if (U_SUCCESS(error_code)) {
+      ucnv_toUChars(cs, result, 12, buffer, 11, &error_code);
+      ucnv_close(cs);
+      if (U_SUCCESS(error_code)) {
+        return result;
+      }
+    }
+    delete[] result;
+    return NULL;
+  }
+
+  // No preflight needed here, we will be bigger.
+  UChar* output_buffer = new UChar[name_bytes->size() + 1];
+  memset(output_buffer, 0, sizeof(UChar) * (name_bytes->size() + 1));
+  int32_t length = ucnv_toUChars(cs,
+                                 output_buffer,
+                                 name_bytes->size(),
+                                 reinterpret_cast<char*>(&((*name_bytes)[0])),
+                                 name_bytes->size(),
+                                 &error_code);
+  ucnv_close(cs);
+  if (length > 0) {
+    return output_buffer;
+  }
+
+  delete[] output_buffer;
+  return NULL;
+}
+
+}  // namespace sfntly
diff --git a/sfntly/table/core/name_table.h b/sfntly/table/core/name_table.h
new file mode 100644
index 0000000..4eaafbb
--- /dev/null
+++ b/sfntly/table/core/name_table.h
@@ -0,0 +1,743 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_NAME_TABLE_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_NAME_TABLE_H_
+
+// Must include this before ICU to avoid stdint redefinition issue.
+#include "sfntly/port/type.h"
+
+#include <unicode/ucnv.h>
+#include <unicode/ustring.h>
+
+#include <map>
+#include <utility>
+
+#include "sfntly/port/java_iterator.h"
+#include "sfntly/table/subtable_container_table.h"
+
+namespace sfntly {
+
+// The following code implements the name table defined in TTF/OTF spec, which
+// can be found at http://www.microsoft.com/typography/otspec/name.htm.
+
+// Name IDs defined in TTF/OTF spec.
+struct NameId {
+  enum {
+    kUnknown = -1,
+    kCopyrightNotice = 0,
+    kFontFamilyName = 1,
+    kFontSubfamilyName = 2,
+    kUniqueFontIdentifier = 3,
+    kFullFontName = 4,
+    kVersionString = 5,
+    kPostscriptName = 6,
+    kTrademark = 7,
+    kManufacturerName = 8,
+    kDesigner = 9,
+    kDescription = 10,
+    kVendorURL = 11,
+    kDesignerURL = 12,
+    kLicenseDescription = 13,
+    kLicenseInfoURL = 14,
+    kReserved15 = 15,
+    kPreferredFamily = 16,
+    kPreferredSubfamily = 17,
+    kCompatibleFullName = 18,
+    kSampleText = 19,
+    kPostscriptCID = 20,
+    kWWSFamilyName = 21,
+    kWWSSubfamilyName = 22
+  };
+};
+
+// Unicode language IDs used in Name Records.
+struct UnicodeLanguageId {
+  enum {
+    kUnknown = -1,
+    kAll = 0
+  };
+};
+
+// Macintosh Language IDs (platform ID = 1)
+struct MacintoshLanguageId {
+  enum {
+    kUnknown = -1,
+    kEnglish = 0,
+    kFrench = 1,
+    kGerman = 2,
+    kItalian = 3,
+    kDutch = 4,
+    kSwedish = 5,
+    kSpanish = 6,
+    kDanish = 7,
+    kPortuguese = 8,
+    kNorwegian = 9,
+    kHebrew = 10,
+    kJapanese = 11,
+    kArabic = 12,
+    kFinnish = 13,
+    kGreek = 14,
+    kIcelandic = 15,
+    kMaltese = 16,
+    kTurkish = 17,
+    kCroatian = 18,
+    kChinese_Traditional = 19,
+    kUrdu = 20,
+    kHindi = 21,
+    kThai = 22,
+    kKorean = 23,
+    kLithuanian = 24,
+    kPolish = 25,
+    kHungarian = 26,
+    kEstonian = 27,
+    kLatvian = 28,
+    kSami = 29,
+    kFaroese = 30,
+    kFarsiPersian = 31,
+    kRussian = 32,
+    kChinese_Simplified = 33,
+    kFlemish = 34,
+    kIrishGaelic = 35,
+    kAlbanian = 36,
+    kRomanian = 37,
+    kCzech = 38,
+    kSlovak = 39,
+    kSlovenian = 40,
+    kYiddish = 41,
+    kSerbian = 42,
+    kMacedonian = 43,
+    kBulgarian = 44,
+    kUkrainian = 45,
+    kByelorussian = 46,
+    kUzbek = 47,
+    kKazakh = 48,
+    kAzerbaijani_Cyrillic = 49,
+    kAzerbaijani_Arabic = 50,
+    kArmenian = 51,
+    kGeorgian = 52,
+    kMoldavian = 53,
+    kKirghiz = 54,
+    kTajiki = 55,
+    kTurkmen = 56,
+    kMongolian_Mongolian = 57,
+    kMongolian_Cyrillic = 58,
+    kPashto = 59,
+    kKurdish = 60,
+    kKashmiri = 61,
+    kSindhi = 62,
+    kTibetan = 63,
+    kNepali = 64,
+    kSanskrit = 65,
+    kMarathi = 66,
+    kBengali = 67,
+    kAssamese = 68,
+    kGujarati = 69,
+    kPunjabi = 70,
+    kOriya = 71,
+    kMalayalam = 72,
+    kKannada = 73,
+    kTamil = 74,
+    kTelugu = 75,
+    kSinhalese = 76,
+    kBurmese = 77,
+    kKhmer = 78,
+    kLao = 79,
+    kVietnamese = 80,
+    kIndonesian = 81,
+    kTagalong = 82,
+    kMalay_Roman = 83,
+    kMalay_Arabic = 84,
+    kAmharic = 85,
+    kTigrinya = 86,
+    kGalla = 87,
+    kSomali = 88,
+    kSwahili = 89,
+    kKinyarwandaRuanda = 90,
+    kRundi = 91,
+    kNyanjaChewa = 92,
+    kMalagasy = 93,
+    kEsperanto = 94,
+    kWelsh = 128,
+    kBasque = 129,
+    kCatalan = 130,
+    kLatin = 131,
+    kQuenchua = 132,
+    kGuarani = 133,
+    kAymara = 134,
+    kTatar = 135,
+    kUighur = 136,
+    kDzongkha = 137,
+    kJavanese_Roman = 138,
+    kSundanese_Roman = 139,
+    kGalician = 140,
+    kAfrikaans = 141,
+    kBreton = 142,
+    kInuktitut = 143,
+    kScottishGaelic = 144,
+    kManxGaelic = 145,
+    kIrishGaelic_WithDotAbove = 146,
+    kTongan = 147,
+    kGreek_Polytonic = 148,
+    kGreenlandic = 149,
+    kAzerbaijani_Roman = 150
+  };
+};
+
+// Windows Language IDs (platformID = 3)
+struct WindowsLanguageId {
+  enum {
+    kUnknown = -1,
+    kAfrikaans_SouthAfrica = 0x0436,
+    kAlbanian_Albania = 0x041C,
+    kAlsatian_France = 0x0484,
+    kAmharic_Ethiopia = 0x045E,
+    kArabic_Algeria = 0x1401,
+    kArabic_Bahrain = 0x3C01,
+    kArabic_Egypt = 0x0C01,
+    kArabic_Iraq = 0x0801,
+    kArabic_Jordan = 0x2C01,
+    kArabic_Kuwait = 0x3401,
+    kArabic_Lebanon = 0x3001,
+    kArabic_Libya = 0x1001,
+    kArabic_Morocco = 0x1801,
+    kArabic_Oman = 0x2001,
+    kArabic_Qatar = 0x4001,
+    kArabic_SaudiArabia = 0x0401,
+    kArabic_Syria = 0x2801,
+    kArabic_Tunisia = 0x1C01,
+    kArabic_UAE = 0x3801,
+    kArabic_Yemen = 0x2401,
+    kArmenian_Armenia = 0x042B,
+    kAssamese_India = 0x044D,
+    kAzeri_Cyrillic_Azerbaijan = 0x082C,
+    kAzeri_Latin_Azerbaijan = 0x042C,
+    kBashkir_Russia = 0x046D,
+    kBasque_Basque = 0x042D,
+    kBelarusian_Belarus = 0x0423,
+    kBengali_Bangladesh = 0x0845,
+    kBengali_India = 0x0445,
+    kBosnian_Cyrillic_BosniaAndHerzegovina = 0x201A,
+    kBosnian_Latin_BosniaAndHerzegovina = 0x141A,
+    kBreton_France = 0x047E,
+    kBulgarian_Bulgaria = 0x0402,
+    kCatalan_Catalan = 0x0403,
+    kChinese_HongKongSAR = 0x0C04,
+    kChinese_MacaoSAR = 0x1404,
+    kChinese_PeoplesRepublicOfChina = 0x0804,
+    kChinese_Singapore = 0x1004,
+    kChinese_Taiwan = 0x0404,
+    kCorsican_France = 0x0483,
+    kCroatian_Croatia = 0x041A,
+    kCroatian_Latin_BosniaAndHerzegovina = 0x101A,
+    kCzech_CzechRepublic = 0x0405,
+    kDanish_Denmark = 0x0406,
+    kDari_Afghanistan = 0x048C,
+    kDivehi_Maldives = 0x0465,
+    kDutch_Belgium = 0x0813,
+    kDutch_Netherlands = 0x0413,
+    kEnglish_Australia = 0x0C09,
+    kEnglish_Belize = 0x2809,
+    kEnglish_Canada = 0x1009,
+    kEnglish_Caribbean = 0x2409,
+    kEnglish_India = 0x4009,
+    kEnglish_Ireland = 0x1809,
+    kEnglish_Jamaica = 0x2009,
+    kEnglish_Malaysia = 0x4409,
+    kEnglish_NewZealand = 0x1409,
+    kEnglish_RepublicOfThePhilippines = 0x3409,
+    kEnglish_Singapore = 0x4809,
+    kEnglish_SouthAfrica = 0x1C09,
+    kEnglish_TrinidadAndTobago = 0x2C09,
+    kEnglish_UnitedKingdom = 0x0809,
+    kEnglish_UnitedStates = 0x0409,
+    kEnglish_Zimbabwe = 0x3009,
+    kEstonian_Estonia = 0x0425,
+    kFaroese_FaroeIslands = 0x0438,
+    kFilipino_Philippines = 0x0464,
+    kFinnish_Finland = 0x040B,
+    kFrench_Belgium = 0x080C,
+    kFrench_Canada = 0x0C0C,
+    kFrench_France = 0x040C,
+    kFrench_Luxembourg = 0x140c,
+    kFrench_PrincipalityOfMonoco = 0x180C,
+    kFrench_Switzerland = 0x100C,
+    kFrisian_Netherlands = 0x0462,
+    kGalician_Galician = 0x0456,
+    kGeorgian_Georgia = 0x0437,
+    kGerman_Austria = 0x0C07,
+    kGerman_Germany = 0x0407,
+    kGerman_Liechtenstein = 0x1407,
+    kGerman_Luxembourg = 0x1007,
+    kGerman_Switzerland = 0x0807,
+    kGreek_Greece = 0x0408,
+    kGreenlandic_Greenland = 0x046F,
+    kGujarati_India = 0x0447,
+    kHausa_Latin_Nigeria = 0x0468,
+    kHebrew_Israel = 0x040D,
+    kHindi_India = 0x0439,
+    kHungarian_Hungary = 0x040E,
+    kIcelandic_Iceland = 0x040F,
+    kIgbo_Nigeria = 0x0470,
+    kIndonesian_Indonesia = 0x0421,
+    kInuktitut_Canada = 0x045D,
+    kInuktitut_Latin_Canada = 0x085D,
+    kIrish_Ireland = 0x083C,
+    kisiXhosa_SouthAfrica = 0x0434,
+    kisiZulu_SouthAfrica = 0x0435,
+    kItalian_Italy = 0x0410,
+    kItalian_Switzerland = 0x0810,
+    kJapanese_Japan = 0x0411,
+    kKannada_India = 0x044B,
+    kKazakh_Kazakhstan = 0x043F,
+    kKhmer_Cambodia = 0x0453,
+    kKiche_Guatemala = 0x0486,
+    kKinyarwanda_Rwanda = 0x0487,
+    kKiswahili_Kenya = 0x0441,
+    kKonkani_India = 0x0457,
+    kKorean_Korea = 0x0412,
+    kKyrgyz_Kyrgyzstan = 0x0440,
+    kLao_LaoPDR = 0x0454,
+    kLatvian_Latvia = 0x0426,
+    kLithuanian_Lithuania = 0x0427,
+    kLowerSorbian_Germany = 0x082E,
+    kLuxembourgish_Luxembourg = 0x046E,
+    kMacedonian_FYROM_FormerYugoslavRepublicOfMacedonia = 0x042F,
+    kMalay_BruneiDarussalam = 0x083E,
+    kMalay_Malaysia = 0x043E,
+    kMalayalam_India = 0x044C,
+    kMaltese_Malta = 0x043A,
+    kMaori_NewZealand = 0x0481,
+    kMapudungun_Chile = 0x047A,
+    kMarathi_India = 0x044E,
+    kMohawk_Mohawk = 0x047C,
+    kMongolian_Cyrillic_Mongolia = 0x0450,
+    kMongolian_Traditional_PeoplesRepublicOfChina = 0x0850,
+    kNepali_Nepal = 0x0461,
+    kNorwegian_Bokmal_Norway = 0x0414,
+    kNorwegian_Nynorsk_Norway = 0x0814,
+    kOccitan_France = 0x0482,
+    kOriya_India = 0x0448,
+    kPashto_Afghanistan = 0x0463,
+    kPolish_Poland = 0x0415,
+    kPortuguese_Brazil = 0x0416,
+    kPortuguese_Portugal = 0x0816,
+    kPunjabi_India = 0x0446,
+    kQuechua_Bolivia = 0x046B,
+    kQuechua_Ecuador = 0x086B,
+    kQuechua_Peru = 0x0C6B,
+    kRomanian_Romania = 0x0418,
+    kRomansh_Switzerland = 0x0417,
+    kRussian_Russia = 0x0419,
+    kSami_Inari_Finland = 0x243B,
+    kSami_Lule_Norway = 0x103B,
+    kSami_Lule_Sweden = 0x143B,
+    kSami_Northern_Finland = 0x0C3B,
+    kSami_Northern_Norway = 0x043B,
+    kSami_Northern_Sweden = 0x083B,
+    kSami_Skolt_Finland = 0x203B,
+    kSami_Southern_Norway = 0x183B,
+    kSami_Southern_Sweden = 0x1C3B,
+    kSanskrit_India = 0x044F,
+    kSerbian_Cyrillic_BosniaAndHerzegovina = 0x1C1A,
+    kSerbian_Cyrillic_Serbia = 0x0C1A,
+    kSerbian_Latin_BosniaAndHerzegovina = 0x181A,
+    kSerbian_Latin_Serbia = 0x081A,
+    kSesothoSaLeboa_SouthAfrica = 0x046C,
+    kSetswana_SouthAfrica = 0x0432,
+    kSinhala_SriLanka = 0x045B,
+    kSlovak_Slovakia = 0x041B,
+    kSlovenian_Slovenia = 0x0424,
+    kSpanish_Argentina = 0x2C0A,
+    kSpanish_Bolivia = 0x400A,
+    kSpanish_Chile = 0x340A,
+    kSpanish_Colombia = 0x240A,
+    kSpanish_CostaRica = 0x140A,
+    kSpanish_DominicanRepublic = 0x1C0A,
+    kSpanish_Ecuador = 0x300A,
+    kSpanish_ElSalvador = 0x440A,
+    kSpanish_Guatemala = 0x100A,
+    kSpanish_Honduras = 0x480A,
+    kSpanish_Mexico = 0x080A,
+    kSpanish_Nicaragua = 0x4C0A,
+    kSpanish_Panama = 0x180A,
+    kSpanish_Paraguay = 0x3C0A,
+    kSpanish_Peru = 0x280A,
+    kSpanish_PuertoRico = 0x500A,
+    kSpanish_ModernSort_Spain = 0x0C0A,
+    kSpanish_TraditionalSort_Spain = 0x040A,
+    kSpanish_UnitedStates = 0x540A,
+    kSpanish_Uruguay = 0x380A,
+    kSpanish_Venezuela = 0x200A,
+    kSweden_Finland = 0x081D,
+    kSwedish_Sweden = 0x041D,
+    kSyriac_Syria = 0x045A,
+    kTajik_Cyrillic_Tajikistan = 0x0428,
+    kTamazight_Latin_Algeria = 0x085F,
+    kTamil_India = 0x0449,
+    kTatar_Russia = 0x0444,
+    kTelugu_India = 0x044A,
+    kThai_Thailand = 0x041E,
+    kTibetan_PRC = 0x0451,
+    kTurkish_Turkey = 0x041F,
+    kTurkmen_Turkmenistan = 0x0442,
+    kUighur_PRC = 0x0480,
+    kUkrainian_Ukraine = 0x0422,
+    kUpperSorbian_Germany = 0x042E,
+    kUrdu_IslamicRepublicOfPakistan = 0x0420,
+    kUzbek_Cyrillic_Uzbekistan = 0x0843,
+    kUzbek_Latin_Uzbekistan = 0x0443,
+    kVietnamese_Vietnam = 0x042A,
+    kWelsh_UnitedKingdom = 0x0452,
+    kWolof_Senegal = 0x0448,
+    kYakut_Russia = 0x0485,
+    kYi_PRC = 0x0478,
+    kYoruba_Nigeria = 0x046A
+  };
+};
+
+class NameTable : public SubTableContainerTable, public RefCounted<NameTable> {
+ public:
+  // Unique identifier for a given name record.
+  class NameEntryId {
+   public:
+    NameEntryId();  // C++ port only, must provide default constructor.
+    NameEntryId(int32_t platform_id, int32_t encoding_id, int32_t language_id,
+                int32_t name_id);
+    NameEntryId(const NameEntryId&);
+    // Make gcc -Wnon-virtual-dtor happy.
+    virtual ~NameEntryId() {}
+
+    int32_t platform_id() const { return platform_id_; }
+    int32_t encoding_id() const { return encoding_id_; }
+    int32_t language_id() const { return language_id_; }
+    int32_t name_id() const { return name_id_; }
+
+    const NameEntryId& operator=(const NameEntryId& rhs) const;
+    bool operator==(const NameEntryId& rhs) const;
+    bool operator<(const NameEntryId& rhs) const;
+
+    // UNIMPLEMENTED: int hashCode()
+    //                String toString()
+
+   private:
+    mutable int32_t platform_id_;
+    mutable int32_t encoding_id_;
+    mutable int32_t language_id_;
+    mutable int32_t name_id_;
+  };
+
+  class NameEntryBuilder;
+
+  // Class to represent a name entry in the name table.
+  class NameEntry : public RefCounted<NameEntry> {
+   public:
+    NameEntry();
+    NameEntry(const NameEntryId& name_entry_id, const ByteVector& name_bytes);
+    NameEntry(int32_t platform_id,
+              int32_t encoding_id,
+              int32_t language_id,
+              int32_t name_id,
+              const ByteVector& name_bytes);
+    virtual ~NameEntry();
+
+    NameEntryId& name_entry_id() { return name_entry_id_; }
+    int32_t platform_id() const { return name_entry_id_.platform_id(); }
+    int32_t encoding_id() const { return name_entry_id_.encoding_id(); }
+    int32_t language_id() const { return name_entry_id_.language_id(); }
+    int32_t name_id() const { return name_entry_id_.name_id(); }
+
+    // Get the bytes for name.  Returned pointer is the address of private
+    // member of this class, do not attempt to delete.
+    ByteVector* NameAsBytes();
+
+    // C++ port only: get the length of NameAsBytes.
+    int32_t NameBytesLength();
+
+    // Returns the name in Unicode as UChar array.
+    // Note: ICU UChar* convention requires caller to delete[] it.
+    UChar* Name();
+    bool operator==(const NameEntry& rhs) const;
+
+    // UNIMPLEMENTED: String toString()
+    //                int hashCode()
+
+   private:
+    void Init(int32_t platform_id, int32_t encoding_id, int32_t language_id,
+              int32_t name_id, const ByteVector* name_bytes);
+
+    NameEntryId name_entry_id_;
+    ByteVector name_bytes_;
+
+    friend class NameEntryBuilder;
+  };
+
+  // Builder of a name entry.
+  // C++ port: original Java hierarchy inherits from NameEntry.  In C++ port, we
+  // opted not doing so to avoid ref count issues and nasty protected members.
+  class NameEntryBuilder : public RefCounted<NameEntryBuilder> {
+   public:
+    NameEntryBuilder();
+    NameEntryBuilder(const NameEntryId& name_entry_id,
+                     const ByteVector& name_bytes);
+    explicit NameEntryBuilder(const NameEntryId& name_entry_id);
+    explicit NameEntryBuilder(NameEntry* entry);
+    virtual ~NameEntryBuilder();
+
+    virtual void SetName(const UChar* name);
+    virtual void SetName(const ByteVector& name_bytes);
+    virtual void SetName(const ByteVector& name_bytes,
+                         int32_t offset,
+                         int32_t length);
+
+    // C++ port only. CALLER_ATTACH is not added because the lifetime shall be
+    // controlled by this class, therefore the caller shall not increase the ref
+    // count.
+    NameEntry* name_entry() { return name_entry_; }
+
+   private:
+    void Init(int32_t platform_id, int32_t encoding_id, int32_t language_id,
+              int32_t name_id, const ByteVector* name_bytes);
+
+    Ptr<NameEntry> name_entry_;
+  };
+  typedef std::map<NameEntryId, Ptr<NameEntryBuilder> > NameEntryBuilderMap;
+
+  // An interface for a filter to use with the name entry iterator. This allows
+  // name entries to be iterated and only those acceptable to the filter will be
+  // returned.
+  class NameEntryFilter {
+   public:
+    virtual bool Accept(int32_t platform_id,
+                        int32_t encoding_id,
+                        int32_t language_id,
+                        int32_t name_id) = 0;
+    // Make gcc -Wnon-virtual-dtor happy.
+    virtual ~NameEntryFilter() {}
+  };
+
+  // C++ port only: an in-place filter to mimic Java Iterator's filtering.
+  class NameEntryFilterInPlace : public NameEntryFilter {
+   public:
+    NameEntryFilterInPlace(int32_t platform_id,
+                           int32_t encoding_id,
+                           int32_t language_id,
+                           int32_t name_id);
+    // Make gcc -Wnon-virtual-dtor happy.
+    virtual ~NameEntryFilterInPlace() {}
+
+    virtual bool Accept(int32_t platform_id,
+                        int32_t encoding_id,
+                        int32_t language_id,
+                        int32_t name_id);
+
+   private:
+    int32_t platform_id_;
+    int32_t encoding_id_;
+    int32_t language_id_;
+    int32_t name_id_;
+  };
+
+  class NameEntryIterator : public RefIterator<NameEntry, NameTable> {
+   public:
+    // If filter is NULL, filter through all tables.
+    explicit NameEntryIterator(NameTable* table);
+    NameEntryIterator(NameTable* table, NameEntryFilter* filter);
+    virtual ~NameEntryIterator() {}
+
+    virtual bool HasNext();
+    virtual CALLER_ATTACH NameEntry* Next();
+
+   private:
+    int32_t name_index_;
+    NameEntryFilter* filter_;
+  };
+
+  // The builder to construct name table for outputting.
+  class Builder : public SubTableContainerTable::Builder,
+                  public RefCounted<Builder> {
+   public:
+    // Constructor scope altered to public because C++ does not allow base
+    // class to instantiate derived class with protected constructors.
+    Builder(Header* header, WritableFontData* data);
+    Builder(Header* header, ReadableFontData* data);
+
+    static CALLER_ATTACH Builder* CreateBuilder(Header* header,
+                                                WritableFontData* data);
+
+    // Revert the name builders for the name table to the last version that came
+    // from data.
+    void RevertNames();
+
+    // Number of name entry builders contained.
+    int32_t BuilderCount();
+
+    // Note: For C++ port, clear() is not implemented.  The clear() function
+    //       implies completely remove name entry builders, which is easy in
+    //       Java but will take a lot of efforts in C++ to release the builders
+    //       nicely and correctly.
+    // TODO(arthurhsu): IMPLEMENT
+    // Clear the name builders for the name table.
+    // void clear();
+
+    // Check the existance of a name entry builder by key.
+    bool Has(int32_t platform_id, int32_t encoding_id, int32_t language_id,
+             int32_t name_id);
+
+    // Get name entry builder by key.
+    CALLER_ATTACH NameEntryBuilder* NameBuilder(int32_t platform_id,
+        int32_t encoding_id, int32_t language_id, int32_t name_id);
+
+    // Remove name entry builder by key.
+    bool Remove(int32_t platform_id, int32_t encoding_id, int32_t language_id,
+                int32_t name_id);
+
+    // FontDataTable::Builder API implementation
+    virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+    virtual void SubDataSet();
+    virtual int32_t SubDataSizeToSerialize();
+    virtual bool SubReadyToSerialize();
+    virtual int32_t SubSerialize(WritableFontData* new_data);
+
+   private:
+    void Initialize(ReadableFontData* data);
+    NameEntryBuilderMap* GetNameBuilders();
+
+    // Note: callers should use the getter funtion provided above to ensure that
+    // this is lazily initialized instead of accessing directly.
+    NameEntryBuilderMap name_entry_map_;
+  };
+
+  /****************************************************************************
+   * public methods of NameTable class
+   ****************************************************************************/
+  virtual ~NameTable();
+
+  // Get the format used in the name table.
+  virtual int32_t Format();
+
+  // Get the number of names in the name table.
+  virtual int32_t NameCount();
+
+  // Get the platform id for the given name record.
+  virtual int32_t PlatformId(int32_t index);
+
+  // Get the encoding id for the given name record.
+  // see MacintoshEncodingId, WindowsEncodingId, UnicodeEncodingId
+  virtual int32_t EncodingId(int32_t index);
+
+  // Get the language id for the given name record.
+  virtual int32_t LanguageId(int32_t index);
+
+  // Get the name id for given name record.
+  virtual int32_t NameId(int32_t index);
+
+  // Get the name as bytes for the specified name. If there is no entry for the
+  // requested name, then empty vector is returned.
+  virtual void NameAsBytes(int32_t index, ByteVector* b);
+  virtual void NameAsBytes(int32_t platform_id, int32_t encoding_id,
+                           int32_t language_id, int32_t name_id,
+                           ByteVector* b);
+
+  // Get the name as a UChar* for the given name record. If there is no
+  // encoding conversion available for the name record then a best attempt
+  // UChar* will be returned.
+  // Note: ICU UChar* convention requires caller to delete[] it.
+  virtual UChar* Name(int32_t index);
+
+  // Get the name as a UChar* for the specified name. If there is no entry for
+  // the requested name then NULL is returned. If there is no encoding
+  // conversion available for the name then a best attempt UChar* will be
+  // returned.
+  // Note: ICU UChar* convention requires caller to delete[] it.
+  virtual UChar* Name(int32_t platform_id, int32_t encoding_id,
+                      int32_t language_id, int32_t name_id);
+
+  // Note: These functions are renamed in C++ port.  Their original Java name is
+  // nameEntry().
+  virtual CALLER_ATTACH NameEntry* GetNameEntry(int32_t index);
+  virtual CALLER_ATTACH NameEntry* GetNameEntry(int32_t platform_id,
+      int32_t encoding_id, int32_t language_id, int32_t name_id);
+
+  // Note: Not implemented in C++ port due to complexity and low usage.
+  // virtual void names(std::set<NameEntryPtr>*);
+
+  // Get the iterator to iterate through all name entries.
+  virtual CALLER_ATTACH NameEntryIterator* Iterator();
+  virtual CALLER_ATTACH NameEntryIterator* Iterator(NameEntryFilter* filter);
+
+ private:
+  struct Offset {
+    enum {
+      kFormat = 0,
+      kCount = 2,
+      kStringOffset = 4,
+      kNameRecordStart = 6,
+
+      // Format 1 - offset from the end of the name records
+      kLangTagCount = 0,
+      kLangTagRecord = 2,
+
+      kNameRecordSize = 12,
+      // Name Records
+      kNameRecordPlatformId = 0,
+      kNameRecordEncodingId = 2,
+      kNameRecordLanguageId = 4,
+      kNameRecordNameId = 6,
+      kNameRecordStringLength = 8,
+      kNameRecordStringOffset = 10
+    };
+  };
+
+  // The table shall be constructed using Builder, no direct instantiation.
+  NameTable(Header* header, ReadableFontData* data);
+
+  // Get the offset to the string data in the name table.
+  int32_t StringOffset();
+
+  // Get the offset for the given name record.
+  int32_t OffsetForNameRecord(int32_t index);
+
+  // Get the length of the string data for the given name record.
+  int32_t NameLength(int32_t index);
+
+  // Get the offset of the string data for the given name record.
+  int32_t NameOffset(int32_t index);
+
+  // Note: string literals are returned.  Caller shall not attempt to manipulate
+  // the returned pointer.
+  static const char* GetEncodingName(int32_t platform_id, int32_t encoding_id);
+
+  // Note: ICU UConverter* convention requires caller to ucnv_close() it.
+  static UConverter* GetCharset(int32_t platform_id, int32_t encoding_id);
+
+  // Note: Output will be stored in ByteVector* b.  Original data in b will be
+  // erased and replaced with converted name bytes.
+  static void ConvertToNameBytes(const UChar* name, int32_t platform_id,
+                                 int32_t encoding_id, ByteVector* b);
+
+  // Note: ICU UChar* convention requires caller to delete[] it.
+  static UChar* ConvertFromNameBytes(ByteVector* name_bytes,
+                                     int32_t platform_id, int32_t encoding_id);
+};  // class NameTable
+typedef Ptr<NameTable> NameTablePtr;
+typedef Ptr<NameTable::NameEntry> NameEntryPtr;
+typedef Ptr<NameTable::Builder> NameTableBuilderPtr;
+typedef Ptr<NameTable::NameEntryBuilder> NameEntryBuilderPtr;
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_NAME_TABLE_H_
diff --git a/sfntly/table/core/os2_table.cc b/sfntly/table/core/os2_table.cc
new file mode 100644
index 0000000..1fef309
--- /dev/null
+++ b/sfntly/table/core/os2_table.cc
@@ -0,0 +1,610 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/table/core/os2_table.h"
+
+#include <algorithm>
+
+namespace sfntly {
+/******************************************************************************
+ * Constants
+ ******************************************************************************/
+const int64_t CodePageRange::kLatin1_1252 = (int64_t)1 << 0;
+const int64_t CodePageRange::kLatin2_1250 = (int64_t)1 << (int64_t)1;
+const int64_t CodePageRange::kCyrillic_1251 = (int64_t)1 << 2;
+const int64_t CodePageRange::kGreek_1253 = (int64_t)1 << 3;
+const int64_t CodePageRange::kTurkish_1254 = (int64_t)1 << 4;
+const int64_t CodePageRange::kHebrew_1255 = (int64_t)1 << 5;
+const int64_t CodePageRange::kArabic_1256 = (int64_t)1 << 6;
+const int64_t CodePageRange::kWindowsBaltic_1257 = (int64_t)1 << 7;
+const int64_t CodePageRange::kVietnamese_1258 = (int64_t)1 << 8;
+const int64_t CodePageRange::kAlternateANSI9 = (int64_t)1 << 9;
+const int64_t CodePageRange::kAlternateANSI10 = (int64_t)1 << 10;
+const int64_t CodePageRange::kAlternateANSI11 = (int64_t)1 << 11;
+const int64_t CodePageRange::kAlternateANSI12 = (int64_t)1 << 12;
+const int64_t CodePageRange::kAlternateANSI13 = (int64_t)1 << 13;
+const int64_t CodePageRange::kAlternateANSI14 = (int64_t)1 << 14;
+const int64_t CodePageRange::kAlternateANSI15 = (int64_t)1 << 15;
+const int64_t CodePageRange::kThai_874 = (int64_t)1 << 16;
+const int64_t CodePageRange::kJapanJIS_932 = (int64_t)1 << 17;
+const int64_t CodePageRange::kChineseSimplified_936 = (int64_t)1 << 18;
+const int64_t CodePageRange::kKoreanWansung_949 = (int64_t)1 << 19;
+const int64_t CodePageRange::kChineseTraditional_950 = (int64_t)1 << 20;
+const int64_t CodePageRange::kKoreanJohab_1361 = (int64_t)1 << 21;
+const int64_t CodePageRange::kAlternateANSI22 = (int64_t)1 << 22;
+const int64_t CodePageRange::kAlternateANSI23 = (int64_t)1 << 23;
+const int64_t CodePageRange::kAlternateANSI24 = (int64_t)1 << 24;
+const int64_t CodePageRange::kAlternateANSI25 = (int64_t)1 << 25;
+const int64_t CodePageRange::kAlternateANSI26 = (int64_t)1 << 26;
+const int64_t CodePageRange::kAlternateANSI27 = (int64_t)1 << 27;
+const int64_t CodePageRange::kAlternateANSI28 = (int64_t)1 << 28;
+const int64_t CodePageRange::kMacintoshCharacterSet = (int64_t)1 << 29;
+const int64_t CodePageRange::kOEMCharacterSet = (int64_t)1 << 30;
+const int64_t CodePageRange::kSymbolCharacterSet = (int64_t)1 << 31;
+const int64_t CodePageRange::kReservedForOEM32 = (int64_t)1 << 32;
+const int64_t CodePageRange::kReservedForOEM33 = (int64_t)1 << 33;
+const int64_t CodePageRange::kReservedForOEM34 = (int64_t)1 << 34;
+const int64_t CodePageRange::kReservedForOEM35 = (int64_t)1 << 35;
+const int64_t CodePageRange::kReservedForOEM36 = (int64_t)1 << 36;
+const int64_t CodePageRange::kReservedForOEM37 = (int64_t)1 << 37;
+const int64_t CodePageRange::kReservedForOEM38 = (int64_t)1 << 38;
+const int64_t CodePageRange::kReservedForOEM39 = (int64_t)1 << 39;
+const int64_t CodePageRange::kReservedForOEM40 = (int64_t)1 << 40;
+const int64_t CodePageRange::kReservedForOEM41 = (int64_t)1 << 41;
+const int64_t CodePageRange::kReservedForOEM42 = (int64_t)1 << 42;
+const int64_t CodePageRange::kReservedForOEM43 = (int64_t)1 << 43;
+const int64_t CodePageRange::kReservedForOEM44 = (int64_t)1 << 44;
+const int64_t CodePageRange::kReservedForOEM45 = (int64_t)1 << 45;
+const int64_t CodePageRange::kReservedForOEM46 = (int64_t)1 << 46;
+const int64_t CodePageRange::kReservedForOEM47 = (int64_t)1 << 47;
+const int64_t CodePageRange::kIBMGreek_869 = (int64_t)1 << 48;
+const int64_t CodePageRange::kMSDOSRussion_866 = (int64_t)1 << 49;
+const int64_t CodePageRange::kMSDOSNordic_865 = (int64_t)1 << 50;
+const int64_t CodePageRange::kArabic_864 = (int64_t)1 << 51;
+const int64_t CodePageRange::kMSDOSCanadianFrench_863 = (int64_t)1 << 52;
+const int64_t CodePageRange::kHebrew_862 = (int64_t)1 << 53;
+const int64_t CodePageRange::kMSDOSIcelandic_861 = (int64_t)1 << 54;
+const int64_t CodePageRange::kMSDOSPortugese_860 = (int64_t)1 << 55;
+const int64_t CodePageRange::kIBMTurkish_857 = (int64_t)1 << 56;
+const int64_t CodePageRange::kIBMCyrillic_855 = (int64_t)1 << 57;
+const int64_t CodePageRange::kLatin2_852 = (int64_t)1 << 58;
+const int64_t CodePageRange::kMSDOSBaltic_775 = (int64_t)1 << 59;
+const int64_t CodePageRange::kGreek_737 = (int64_t)1 << 60;
+const int64_t CodePageRange::kArabic_708 = (int64_t)1 << 61;
+const int64_t CodePageRange::kLatin1_850 = (int64_t)1 << 62;
+const int64_t CodePageRange::kUS_437 = (int64_t)1 << 63;
+
+/******************************************************************************
+ * struct UnicodeRange
+ ******************************************************************************/
+int32_t UnicodeRange::range(int32_t bit) {
+  if (bit < 0 || bit > kLast) {
+    return -1;
+  }
+  return bit;
+}
+
+/******************************************************************************
+ * class OS2Table
+ ******************************************************************************/
+OS2Table::~OS2Table() {}
+
+int32_t OS2Table::TableVersion() {
+  return data_->ReadUShort(Offset::kVersion);
+}
+
+int32_t OS2Table::XAvgCharWidth() {
+  return data_->ReadShort(Offset::kXAvgCharWidth);
+}
+
+int32_t OS2Table::UsWeightClass() {
+  return data_->ReadUShort(Offset::kUsWeightClass);
+}
+
+int32_t OS2Table::UsWidthClass() {
+  return data_->ReadUShort(Offset::kUsWidthClass);
+}
+
+int32_t OS2Table::FsType() {
+  return data_->ReadUShort(Offset::kFsType);
+}
+
+int32_t OS2Table::YSubscriptXSize() {
+  return data_->ReadShort(Offset::kYSubscriptXSize);
+}
+
+int32_t OS2Table::YSubscriptYSize() {
+  return data_->ReadShort(Offset::kYSubscriptYSize);
+}
+
+int32_t OS2Table::YSubscriptXOffset() {
+  return data_->ReadShort(Offset::kYSubscriptXOffset);
+}
+
+int32_t OS2Table::YSubscriptYOffset() {
+  return data_->ReadShort(Offset::kYSubscriptYOffset);
+}
+
+int32_t OS2Table::YSuperscriptXSize() {
+  return data_->ReadShort(Offset::kYSuperscriptXSize);
+}
+
+int32_t OS2Table::YSuperscriptYSize() {
+  return data_->ReadShort(Offset::kYSuperscriptYSize);
+}
+
+int32_t OS2Table::YSuperscriptXOffset() {
+  return data_->ReadShort(Offset::kYSuperscriptXOffset);
+}
+
+int32_t OS2Table::YSuperscriptYOffset() {
+  return data_->ReadShort(Offset::kYSuperscriptYOffset);
+}
+
+int32_t OS2Table::YStrikeoutSize() {
+  return data_->ReadShort(Offset::kYStrikeoutSize);
+}
+
+int32_t OS2Table::YStrikeoutPosition() {
+  return data_->ReadShort(Offset::kYStrikeoutPosition);
+}
+
+int32_t OS2Table::SFamilyClass() {
+  return data_->ReadShort(Offset::kSFamilyClass);
+}
+
+void OS2Table::Panose(ByteVector* value) {
+  assert(value);
+  value->clear();
+  value->resize(10);
+  data_->ReadBytes(Offset::kPanose, &((*value)[0]), 0, 10);
+}
+
+int64_t OS2Table::UlUnicodeRange1() {
+  return data_->ReadULong(Offset::kUlUnicodeRange1);
+}
+
+int64_t OS2Table::UlUnicodeRange2() {
+  return data_->ReadULong(Offset::kUlUnicodeRange2);
+}
+
+int64_t OS2Table::UlUnicodeRange3() {
+  return data_->ReadULong(Offset::kUlUnicodeRange3);
+}
+
+int64_t OS2Table::UlUnicodeRange4() {
+  return data_->ReadULong(Offset::kUlUnicodeRange4);
+}
+
+void OS2Table::AchVendId(ByteVector* b) {
+  assert(b);
+  b->clear();
+  b->resize(4);
+  data_->ReadBytes(Offset::kAchVendId, &((*b)[0]), 0, 4);
+}
+
+int32_t OS2Table::FsSelection() {
+  return data_->ReadUShort(Offset::kFsSelection);
+}
+
+int32_t OS2Table::UsFirstCharIndex() {
+  return data_->ReadUShort(Offset::kUsFirstCharIndex);
+}
+
+int32_t OS2Table::UsLastCharIndex() {
+  return data_->ReadUShort(Offset::kUsLastCharIndex);
+}
+
+int32_t OS2Table::STypoAscender() {
+  return data_->ReadShort(Offset::kSTypoAscender);
+}
+
+int32_t OS2Table::STypoDescender() {
+  return data_->ReadShort(Offset::kSTypoDescender);
+}
+
+int32_t OS2Table::STypoLineGap() {
+  return data_->ReadShort(Offset::kSTypoLineGap);
+}
+
+int32_t OS2Table::UsWinAscent() {
+  return data_->ReadUShort(Offset::kUsWinAscent);
+}
+
+int32_t OS2Table::UsWinDescent() {
+  return data_->ReadUShort(Offset::kUsWinDescent);
+}
+
+int64_t OS2Table::UlCodePageRange1() {
+  return data_->ReadULong(Offset::kUlCodePageRange1);
+}
+
+int64_t OS2Table::UlCodePageRange2() {
+  return data_->ReadULong(Offset::kUlCodePageRange2);
+}
+
+int32_t OS2Table::SxHeight() {
+  return data_->ReadShort(Offset::kSxHeight);
+}
+
+int32_t OS2Table::SCapHeight() {
+  return data_->ReadShort(Offset::kSCapHeight);
+}
+
+int32_t OS2Table::UsDefaultChar() {
+  return data_->ReadUShort(Offset::kUsDefaultChar);
+}
+
+int32_t OS2Table::UsBreakChar() {
+  return data_->ReadUShort(Offset::kUsBreakChar);
+}
+
+int32_t OS2Table::UsMaxContext() {
+  return data_->ReadUShort(Offset::kUsMaxContext);
+}
+
+OS2Table::OS2Table(Header* header, ReadableFontData* data)
+    : Table(header, data) {
+}
+
+/******************************************************************************
+ * class OS2Table::Builder
+ ******************************************************************************/
+OS2Table::Builder::Builder(Header* header, WritableFontData* data)
+    : TableBasedTableBuilder(header, data) {
+}
+
+OS2Table::Builder::Builder(Header* header, ReadableFontData* data)
+    : TableBasedTableBuilder(header, data) {
+}
+
+OS2Table::Builder::~Builder() {}
+
+CALLER_ATTACH FontDataTable* OS2Table::Builder::SubBuildTable(
+    ReadableFontData* data) {
+  FontDataTablePtr table = new OS2Table(header(), data);
+  return table.Detach();
+}
+
+CALLER_ATTACH OS2Table::Builder*
+    OS2Table::Builder::CreateBuilder(Header* header,
+                                     WritableFontData* data) {
+  Ptr<OS2Table::Builder> builder;
+  builder = new OS2Table::Builder(header, data);
+  return builder.Detach();
+}
+
+int32_t OS2Table::Builder::TableVersion() {
+  return InternalReadData()->ReadUShort(Offset::kVersion);
+}
+
+void OS2Table::Builder::SetTableVersion(int32_t version) {
+  InternalWriteData()->WriteUShort(Offset::kVersion, version);
+}
+
+int32_t OS2Table::Builder::XAvgCharWidth() {
+  return InternalReadData()->ReadShort(Offset::kXAvgCharWidth);
+}
+
+void OS2Table::Builder::SetXAvgCharWidth(int32_t width) {
+  InternalWriteData()->WriteShort(Offset::kXAvgCharWidth, width);
+}
+
+int32_t OS2Table::Builder::UsWeightClass() {
+  return InternalReadData()->ReadUShort(Offset::kUsWeightClass);
+}
+
+void OS2Table::Builder::SetUsWeightClass(int32_t weight) {
+  InternalWriteData()->WriteUShort(Offset::kUsWeightClass, weight);
+}
+
+int32_t OS2Table::Builder::UsWidthClass() {
+  return InternalReadData()->ReadUShort(Offset::kUsWidthClass);
+}
+
+void OS2Table::Builder::SetUsWidthClass(int32_t width) {
+  InternalWriteData()->WriteUShort(Offset::kUsWidthClass, width);
+}
+
+int32_t OS2Table::Builder::FsType() {
+  return InternalReadData()->ReadUShort(Offset::kFsType);
+}
+
+void OS2Table::Builder::SetFsType(int32_t fs_type) {
+  InternalWriteData()->WriteUShort(Offset::kFsType, fs_type);
+}
+
+int32_t OS2Table::Builder::YSubscriptXSize() {
+  return InternalReadData()->ReadShort(Offset::kYSubscriptXSize);
+}
+
+void OS2Table::Builder::SetYSubscriptXSize(int32_t size) {
+  InternalWriteData()->WriteShort(Offset::kYSubscriptXSize, size);
+}
+
+int32_t OS2Table::Builder::YSubscriptYSize() {
+  return InternalReadData()->ReadShort(Offset::kYSubscriptYSize);
+}
+
+void OS2Table::Builder::SetYSubscriptYSize(int32_t size) {
+  InternalWriteData()->WriteShort(Offset::kYSubscriptYSize, size);
+}
+
+int32_t OS2Table::Builder::YSubscriptXOffset() {
+  return InternalReadData()->ReadShort(Offset::kYSubscriptXOffset);
+}
+
+void OS2Table::Builder::SetYSubscriptXOffset(int32_t offset) {
+  InternalWriteData()->WriteShort(Offset::kYSubscriptXOffset, offset);
+}
+
+int32_t OS2Table::Builder::YSubscriptYOffset() {
+  return InternalReadData()->ReadShort(Offset::kYSubscriptYOffset);
+}
+
+void OS2Table::Builder::SetYSubscriptYOffset(int32_t offset) {
+  InternalWriteData()->WriteShort(Offset::kYSubscriptYOffset, offset);
+}
+
+int32_t OS2Table::Builder::YSuperscriptXSize() {
+  return InternalReadData()->ReadShort(Offset::kYSuperscriptXSize);
+}
+
+void OS2Table::Builder::SetYSuperscriptXSize(int32_t size) {
+  InternalWriteData()->WriteShort(Offset::kYSuperscriptXSize, size);
+}
+
+int32_t OS2Table::Builder::YSuperscriptYSize() {
+  return InternalReadData()->ReadShort(Offset::kYSuperscriptYSize);
+}
+
+void OS2Table::Builder::SetYSuperscriptYSize(int32_t size) {
+  InternalWriteData()->WriteShort(Offset::kYSuperscriptYSize, size);
+}
+
+int32_t OS2Table::Builder::YSuperscriptXOffset() {
+  return InternalReadData()->ReadShort(Offset::kYSuperscriptXOffset);
+}
+
+void OS2Table::Builder::SetYSuperscriptXOffset(int32_t offset) {
+  InternalWriteData()->WriteShort(Offset::kYSuperscriptXOffset, offset);
+}
+
+int32_t OS2Table::Builder::YSuperscriptYOffset() {
+  return InternalReadData()->ReadShort(Offset::kYSuperscriptYOffset);
+}
+
+void OS2Table::Builder::SetYSuperscriptYOffset(int32_t offset) {
+  InternalWriteData()->WriteShort(Offset::kYSuperscriptYOffset, offset);
+}
+
+int32_t OS2Table::Builder::YStrikeoutSize() {
+  return InternalReadData()->ReadShort(Offset::kYStrikeoutSize);
+}
+
+void OS2Table::Builder::SetYStrikeoutSize(int32_t size) {
+  InternalWriteData()->WriteShort(Offset::kYStrikeoutSize, size);
+}
+
+int32_t OS2Table::Builder::YStrikeoutPosition() {
+  return InternalReadData()->ReadShort(Offset::kYStrikeoutPosition);
+}
+
+void OS2Table::Builder::SetYStrikeoutPosition(int32_t position) {
+  InternalWriteData()->WriteShort(Offset::kYStrikeoutPosition, position);
+}
+
+int32_t OS2Table::Builder::SFamilyClass() {
+  return InternalReadData()->ReadShort(Offset::kSFamilyClass);
+}
+
+void OS2Table::Builder::SetSFamilyClass(int32_t family) {
+  InternalWriteData()->WriteShort(Offset::kSFamilyClass, family);
+}
+
+void OS2Table::Builder::Panose(ByteVector* value) {
+  assert(value);
+  value->clear();
+  value->resize(Offset::kPanoseLength);
+  InternalReadData()->ReadBytes(Offset::kPanose,
+                                &((*value)[0]),
+                                0,
+                                Offset::kPanoseLength);
+}
+
+void OS2Table::Builder::SetPanose(ByteVector* panose) {
+  assert(panose);
+  if (panose->size() != Offset::kPanoseLength) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IllegalArgumentException("Panose bytes must be exactly 10 in length");
+#endif
+    return;
+  }
+  InternalWriteData()->WriteBytes(Offset::kPanose, panose);
+}
+
+int64_t OS2Table::Builder::UlUnicodeRange1() {
+  return InternalReadData()->ReadULong(Offset::kUlUnicodeRange1);
+}
+
+void OS2Table::Builder::SetUlUnicodeRange1(int64_t range) {
+  InternalWriteData()->WriteULong(Offset::kUlUnicodeRange1, range);
+}
+
+int64_t OS2Table::Builder::UlUnicodeRange2() {
+  return InternalReadData()->ReadULong(Offset::kUlUnicodeRange2);
+}
+
+void OS2Table::Builder::SetUlUnicodeRange2(int64_t range) {
+  InternalWriteData()->WriteULong(Offset::kUlUnicodeRange2, range);
+}
+
+int64_t OS2Table::Builder::UlUnicodeRange3() {
+  return InternalReadData()->ReadULong(Offset::kUlUnicodeRange3);
+}
+
+void OS2Table::Builder::SetUlUnicodeRange3(int64_t range) {
+  InternalWriteData()->WriteULong(Offset::kUlUnicodeRange3, range);
+}
+
+int64_t OS2Table::Builder::UlUnicodeRange4() {
+  return InternalReadData()->ReadULong(Offset::kUlUnicodeRange4);
+}
+
+void OS2Table::Builder::SetUlUnicodeRange4(int64_t range) {
+  InternalWriteData()->WriteULong(Offset::kUlUnicodeRange4, range);
+}
+
+void OS2Table::Builder::AchVendId(ByteVector* b) {
+  assert(b);
+  b->clear();
+  b->resize(4);
+  InternalReadData()->ReadBytes(Offset::kAchVendId, &((*b)[0]), 0, 4);
+}
+
+void OS2Table::Builder::SetAchVendId(ByteVector* b) {
+  assert(b);
+  assert(b->size());
+  InternalWriteData()->WriteBytesPad(Offset::kAchVendId,
+                                     b,
+                                     0,
+                                     std::min<size_t>(
+                                         (size_t)Offset::kAchVendIdLength,
+                                         b->size()),
+                                     static_cast<byte_t>(' '));
+}
+
+int32_t OS2Table::Builder::FsSelection() {
+  return InternalReadData()->ReadUShort(Offset::kFsSelection);
+}
+
+void OS2Table::Builder::SetFsSelection(int32_t fs_selection) {
+  InternalWriteData()->WriteUShort(Offset::kFsSelection, fs_selection);
+}
+
+int32_t OS2Table::Builder::UsFirstCharIndex() {
+  return InternalReadData()->ReadUShort(Offset::kUsFirstCharIndex);
+}
+
+void OS2Table::Builder::SetUsFirstCharIndex(int32_t first_index) {
+  InternalWriteData()->WriteUShort(Offset::kUsFirstCharIndex, first_index);
+}
+
+int32_t OS2Table::Builder::UsLastCharIndex() {
+  return InternalReadData()->ReadUShort(Offset::kUsLastCharIndex);
+}
+
+void OS2Table::Builder::SetUsLastCharIndex(int32_t last_index) {
+  InternalWriteData()->WriteUShort(Offset::kUsLastCharIndex, last_index);
+}
+
+int32_t OS2Table::Builder::STypoAscender() {
+  return InternalReadData()->ReadShort(Offset::kSTypoAscender);
+}
+
+void OS2Table::Builder::SetSTypoAscender(int32_t ascender) {
+  InternalWriteData()->WriteShort(Offset::kSTypoAscender, ascender);
+}
+
+int32_t OS2Table::Builder::STypoDescender() {
+  return InternalReadData()->ReadShort(Offset::kSTypoDescender);
+}
+
+void OS2Table::Builder::SetSTypoDescender(int32_t descender) {
+  InternalWriteData()->WriteShort(Offset::kSTypoDescender, descender);
+}
+
+int32_t OS2Table::Builder::STypoLineGap() {
+  return InternalReadData()->ReadShort(Offset::kSTypoLineGap);
+}
+
+void OS2Table::Builder::SetSTypoLineGap(int32_t line_gap) {
+  InternalWriteData()->WriteShort(Offset::kSTypoLineGap, line_gap);
+}
+
+int32_t OS2Table::Builder::UsWinAscent() {
+  return InternalReadData()->ReadUShort(Offset::kUsWinAscent);
+}
+
+void OS2Table::Builder::SetUsWinAscent(int32_t ascent) {
+  InternalWriteData()->WriteUShort(Offset::kUsWinAscent, ascent);
+}
+
+int32_t OS2Table::Builder::UsWinDescent() {
+  return InternalReadData()->ReadUShort(Offset::kUsWinDescent);
+}
+
+void OS2Table::Builder::SetUsWinDescent(int32_t descent) {
+  InternalWriteData()->WriteUShort(Offset::kUsWinDescent, descent);
+}
+
+int64_t OS2Table::Builder::UlCodePageRange1() {
+  return InternalReadData()->ReadULong(Offset::kUlCodePageRange1);
+}
+
+void OS2Table::Builder::SetUlCodePageRange1(int64_t range) {
+  InternalWriteData()->WriteULong(Offset::kUlCodePageRange1, range);
+}
+
+int64_t OS2Table::Builder::UlCodePageRange2() {
+  return InternalReadData()->ReadULong(Offset::kUlCodePageRange2);
+}
+
+void OS2Table::Builder::SetUlCodePageRange2(int64_t range) {
+  InternalWriteData()->WriteULong(Offset::kUlCodePageRange2, range);
+}
+
+int32_t OS2Table::Builder::SxHeight() {
+  return InternalReadData()->ReadShort(Offset::kSxHeight);
+}
+
+void OS2Table::Builder::SetSxHeight(int32_t height) {
+  InternalWriteData()->WriteShort(Offset::kSxHeight, height);
+}
+
+int32_t OS2Table::Builder::SCapHeight() {
+  return InternalReadData()->ReadShort(Offset::kSCapHeight);
+}
+
+void OS2Table::Builder::SetSCapHeight(int32_t height) {
+  InternalWriteData()->WriteShort(Offset::kSCapHeight, height);
+}
+
+int32_t OS2Table::Builder::UsDefaultChar() {
+  return InternalReadData()->ReadUShort(Offset::kUsDefaultChar);
+}
+
+void OS2Table::Builder::SetUsDefaultChar(int32_t default_char) {
+  InternalWriteData()->WriteUShort(Offset::kUsDefaultChar, default_char);
+}
+
+int32_t OS2Table::Builder::UsBreakChar() {
+  return InternalReadData()->ReadUShort(Offset::kUsBreakChar);
+}
+
+void OS2Table::Builder::SetUsBreakChar(int32_t break_char) {
+  InternalWriteData()->WriteUShort(Offset::kUsBreakChar, break_char);
+}
+
+int32_t OS2Table::Builder::UsMaxContext() {
+  return InternalReadData()->ReadUShort(Offset::kUsMaxContext);
+}
+
+void OS2Table::Builder::SetUsMaxContext(int32_t max_context) {
+  InternalWriteData()->WriteUShort(Offset::kUsMaxContext, max_context);
+}
+
+}  // namespace sfntly
diff --git a/sfntly/table/core/os2_table.h b/sfntly/table/core/os2_table.h
new file mode 100644
index 0000000..00d26d2
--- /dev/null
+++ b/sfntly/table/core/os2_table.h
@@ -0,0 +1,508 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_OS2_TABLE_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_OS2_TABLE_H_
+
+#include "sfntly/port/refcount.h"
+#include "sfntly/table/table.h"
+#include "sfntly/table/table_based_table_builder.h"
+
+namespace sfntly {
+
+struct WeightClass {
+  enum {
+    kThin = 100,
+    kExtraLight = 200,
+    kUltraLight = 200,
+    kLight = 300,
+    kNormal = 400,
+    kRegular = 400,
+    kMedium = 500,
+    kSemiBold = 600,
+    kDemiBold = 600,
+    kBold = 700,
+    kExtraBold = 800,
+    kUltraBold = 800,
+    kBlack = 900,
+    kHeavy = 900
+  };
+};
+
+struct WidthClass {
+  enum {
+    kUltraCondensed = 1,
+    kExtraCondensed = 2,
+    kCondensed = 3,
+    kSemiCondensed = 4,
+    kMedium = 5,
+    kNormal = 5,
+    kSemiExpanded = 6,
+    kExpanded = 7,
+    kExtraExpanded = 8,
+    kUltraExpanded = 9
+  };
+};
+
+// Flags to indicate the embedding licensing rights for a font.
+struct EmbeddingFlags {
+  enum {
+    kReserved0 = 1 << 0,
+    kRestrictedLicenseEmbedding = 1 << 1,
+    kPreviewAndPrintEmbedding = 1 << 2,
+    kEditableEmbedding = 1 << 3,
+    kReserved4 = 1 << 4,
+    kReserved5 = 1 << 5,
+    kReserved6 = 1 << 6,
+    kReserved7 = 1 << 7,
+    kNoSubsetting = 1 << 8,
+    kBitmapEmbeddingOnly = 1 << 9,
+    kReserved10 = 1 << 10,
+    kReserved11 = 1 << 11,
+    kReserved12 = 1 << 12,
+    kReserved13 = 1 << 13,
+    kReserved14 = 1 << 14,
+    kReserved15 = 1 << 15
+  };
+};
+
+struct UnicodeRange {
+  enum {
+    // Do NOT reorder. This enum relies on the ordering of the data matching the
+    // ordinal numbers of the properties.
+    kBasicLatin,
+    kLatin1Supplement,
+    kLatinExtendedA,
+    kLatinExtendedB,
+    kIPAExtensions,
+    kSpacingModifierLetters,
+    kCombiningDiacriticalMarks,
+    kGreekAndCoptic,
+    kCoptic,
+    kCyrillic,
+    kArmenian,
+    kHebrew,
+    kVai,
+    kArabic,
+    kNKo,
+    kDevanagari,
+    kBengali,
+    kGurmukhi,
+    kGujarati,
+    kOriya,
+    kTamil,
+    kTelugu,
+    kKannada,
+    kMalayalam,
+    kThai,
+    kLao,
+    kGeorgian,
+    kBalinese,
+    kHangulJamo,
+    kLatinExtendedAdditional,
+    kGreekExtended,
+    kGeneralPunctuation,
+    kSuperscriptsAndSubscripts,
+    kCurrencySymbols,
+    kNumberForms,
+    kArrows,
+    kMathematicalOperators,
+    kMiscTechnical,
+    kControlPictures,
+    kOCR,
+    kEnclosedAlphanumerics,
+    kBoxDrawing,
+    kBlockElements,
+    kGeometricShapes,
+    kMiscSymbols,
+    kDingbats,
+    kCJKSymbolsAndPunctuation,
+    kHiragana,
+    kKatakana,
+    kBopomofo,
+    kHangulCompatibilityJamo,
+    kPhagspa,
+    kEnclosedCJKLettersAndMonths,
+    kCJKCompatibility,
+    kHangulSyllables,
+    kNonPlane0,
+    kPhoenician,
+    kCJKUnifiedIdeographs,
+    kPrivateUseAreaPlane0,
+    kCJKStrokes,
+    kAlphabeticPresentationForms,
+    kArabicPresentationFormsA,
+    kCombiningHalfMarks,
+    kVerticalForms,
+    kSmallFormVariants,
+    kArabicPresentationFormsB,
+    kHalfwidthAndFullwidthForms,
+    kSpecials,
+    kTibetan,
+    kSyriac,
+    kThaana,
+    kSinhala,
+    kMyanmar,
+    kEthiopic,
+    kCherokee,
+    kUnifiedCanadianAboriginalSyllabics,
+    kOgham,
+    kRunic,
+    kKhmer,
+    kMongolian,
+    kBraillePatterns,
+    kYiSyllables,
+    kTagalog,
+    kOldItalic,
+    kGothic,
+    kDeseret,
+    kMusicalSymbols,
+    kMathematicalAlphanumericSymbols,
+    kPrivateUsePlane15And16,
+    kVariationSelectors,
+    kTags,
+    kLimbu,
+    kTaiLe,
+    kNewTaiLue,
+    kBuginese,
+    kGlagolitic,
+    kTifnagh,
+    kYijingHexagramSymbols,
+    kSylotiNagari,
+    kLinearB,
+    kAncientGreekNumbers,
+    kUgaritic,
+    kOldPersian,
+    kShavian,
+    kOsmanya,
+    kCypriotSyllabary,
+    kKharoshthi,
+    kTaiXuanJingSymbols,
+    kCuneiform,
+    kCountingRodNumerals,
+    kSudanese,
+    kLepcha,
+    kOlChiki,
+    kSaurashtra,
+    kKayahLi,
+    kRejang,
+    kCharm,
+    kAncientSymbols,
+    kPhaistosDisc,
+    kCarian,
+    kDominoTiles,
+    kReserved123,
+    kReserved124,
+    kReserved125,
+    kReserved126,
+    kReserved127,
+    kLast = kReserved127
+  };
+
+  int32_t range(int32_t bit);
+  // UNIMPLEMENTED: EnumSet<UnicodeRange> asSet(long range1, long range2,
+  //                                            long range3, long range4)
+  //                long[] asArray(EnumSet<UnicodeRange> rangeSet)
+};
+
+struct FsSelection {
+  enum {
+    kITALIC = 1 << 0,
+    kUNDERSCORE = 1 << 1,
+    kNEGATIVE = 1 << 2,
+    kOUTLINED = 1 << 3,
+    kSTRIKEOUT = 1 << 4,
+    kBOLD = 1 << 5,
+    kREGULAR = 1 << 6,
+    kUSE_TYPO_METRICS = 1 << 7,
+    kWWS = 1 << 8,
+    kOBLIQUE = 1 << 9
+  };
+  // UNIMPLEMENTED: EnumSet<FsSelection> asSet(long range1, long range2,
+  //                                           long range3, long range4)
+  //                long[] asArray(EnumSet<FsSelection> rangeSet)
+};
+
+// C++ port only: C++ does not support 64-bit enums until C++0x.  For better
+// portability, we need to use static const int64_t instead.
+struct CodePageRange {
+  static const int64_t kLatin1_1252;
+  static const int64_t kLatin2_1250;
+  static const int64_t kCyrillic_1251;
+  static const int64_t kGreek_1253;
+  static const int64_t kTurkish_1254;
+  static const int64_t kHebrew_1255;
+  static const int64_t kArabic_1256;
+  static const int64_t kWindowsBaltic_1257;
+  static const int64_t kVietnamese_1258;
+  static const int64_t kAlternateANSI9;
+  static const int64_t kAlternateANSI10;
+  static const int64_t kAlternateANSI11;
+  static const int64_t kAlternateANSI12;
+  static const int64_t kAlternateANSI13;
+  static const int64_t kAlternateANSI14;
+  static const int64_t kAlternateANSI15;
+  static const int64_t kThai_874;
+  static const int64_t kJapanJIS_932;
+  static const int64_t kChineseSimplified_936;
+  static const int64_t kKoreanWansung_949;
+  static const int64_t kChineseTraditional_950;
+  static const int64_t kKoreanJohab_1361;
+  static const int64_t kAlternateANSI22;
+  static const int64_t kAlternateANSI23;
+  static const int64_t kAlternateANSI24;
+  static const int64_t kAlternateANSI25;
+  static const int64_t kAlternateANSI26;
+  static const int64_t kAlternateANSI27;
+  static const int64_t kAlternateANSI28;
+  static const int64_t kMacintoshCharacterSet;
+  static const int64_t kOEMCharacterSet;
+  static const int64_t kSymbolCharacterSet;
+  static const int64_t kReservedForOEM32;
+  static const int64_t kReservedForOEM33;
+  static const int64_t kReservedForOEM34;
+  static const int64_t kReservedForOEM35;
+  static const int64_t kReservedForOEM36;
+  static const int64_t kReservedForOEM37;
+  static const int64_t kReservedForOEM38;
+  static const int64_t kReservedForOEM39;
+  static const int64_t kReservedForOEM40;
+  static const int64_t kReservedForOEM41;
+  static const int64_t kReservedForOEM42;
+  static const int64_t kReservedForOEM43;
+  static const int64_t kReservedForOEM44;
+  static const int64_t kReservedForOEM45;
+  static const int64_t kReservedForOEM46;
+  static const int64_t kReservedForOEM47;
+  static const int64_t kIBMGreek_869;
+  static const int64_t kMSDOSRussion_866;
+  static const int64_t kMSDOSNordic_865;
+  static const int64_t kArabic_864;
+  static const int64_t kMSDOSCanadianFrench_863;
+  static const int64_t kHebrew_862;
+  static const int64_t kMSDOSIcelandic_861;
+  static const int64_t kMSDOSPortugese_860;
+  static const int64_t kIBMTurkish_857;
+  static const int64_t kIBMCyrillic_855;
+  static const int64_t kLatin2_852;
+  static const int64_t kMSDOSBaltic_775;
+  static const int64_t kGreek_737;
+  static const int64_t kArabic_708;
+  static const int64_t kLatin1_850;
+  static const int64_t kUS_437;
+
+  // UNIMPLEMENTED: EnumSet<CodePageRange> asSet(long range1, long range2,
+  //                                             long range3, long range4)
+  //                long[] asArray(EnumSet<CodePageRange> rangeSet)
+};
+
+// An OS/2 table - 'OS/2'.
+class OS2Table : public Table, public RefCounted<OS2Table> {
+ public:
+  // A builder for the OS/2 table = 'OS/2'.
+  class Builder : public TableBasedTableBuilder, public RefCounted<Builder> {
+   public:
+    Builder(Header* header, WritableFontData* data);
+    Builder(Header* header, ReadableFontData* data);
+    virtual ~Builder();
+    virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+
+    static CALLER_ATTACH Builder* CreateBuilder(Header* header,
+                                                WritableFontData* data);
+
+    int32_t TableVersion();
+    void SetTableVersion(int32_t version);
+    int32_t XAvgCharWidth();
+    void SetXAvgCharWidth(int32_t width);
+    int32_t UsWeightClass();
+    void SetUsWeightClass(int32_t weight);
+    int32_t UsWidthClass();
+    void SetUsWidthClass(int32_t width);
+    // UNIMPLEMENTED: EnumSet<EmbeddingFlags> fsType()
+    //                void setFsType(EnumSeT<EmbeddingFlags> flagSet)
+    int32_t FsType();
+    void SetFsType(int32_t fs_type);
+    int32_t YSubscriptXSize();
+    void SetYSubscriptXSize(int32_t size);
+    int32_t YSubscriptYSize();
+    void SetYSubscriptYSize(int32_t size);
+    int32_t YSubscriptXOffset();
+    void SetYSubscriptXOffset(int32_t offset);
+    int32_t YSubscriptYOffset();
+    void SetYSubscriptYOffset(int32_t offset);
+    int32_t YSuperscriptXSize();
+    void SetYSuperscriptXSize(int32_t size);
+    int32_t YSuperscriptYSize();
+    void SetYSuperscriptYSize(int32_t size);
+    int32_t YSuperscriptXOffset();
+    void SetYSuperscriptXOffset(int32_t offset);
+    int32_t YSuperscriptYOffset();
+    void SetYSuperscriptYOffset(int32_t offset);
+    int32_t YStrikeoutSize();
+    void SetYStrikeoutSize(int32_t size);
+    int32_t YStrikeoutPosition();
+    void SetYStrikeoutPosition(int32_t position);
+    int32_t SFamilyClass();
+    void SetSFamilyClass(int32_t family);
+    void Panose(ByteVector* value);
+    void SetPanose(ByteVector* panose);
+    int64_t UlUnicodeRange1();
+    void SetUlUnicodeRange1(int64_t range);
+    int64_t UlUnicodeRange2();
+    void SetUlUnicodeRange2(int64_t range);
+    int64_t UlUnicodeRange3();
+    void SetUlUnicodeRange3(int64_t range);
+    int64_t UlUnicodeRange4();
+    void SetUlUnicodeRange4(int64_t range);
+    // UNIMPLEMENTED: EnumSet<UnicodeRange> UlUnicodeRange()
+    //                setUlUnicodeRange(EnumSet<UnicodeRange> rangeSet)
+    void AchVendId(ByteVector* b);
+    // This field is 4 bytes in length and only the first 4 bytes of the byte
+    // array will be written. If the byte array is less than 4 bytes it will be
+    // padded out with space characters (0x20).
+    // @param b ach Vendor Id
+    void SetAchVendId(ByteVector* b);
+    // UNIMPLEMENTED: public EnumSet<FsSelection> fsSelection()
+    int32_t FsSelection();
+    void SetFsSelection(int32_t fs_selection);
+    int32_t UsFirstCharIndex();
+    void SetUsFirstCharIndex(int32_t first_index);
+    int32_t UsLastCharIndex();
+    void SetUsLastCharIndex(int32_t last_index);
+    int32_t STypoAscender();
+    void SetSTypoAscender(int32_t ascender);
+    int32_t STypoDescender();
+    void SetSTypoDescender(int32_t descender);
+    int32_t STypoLineGap();
+    void SetSTypoLineGap(int32_t line_gap);
+    int32_t UsWinAscent();
+    void SetUsWinAscent(int32_t ascent);
+    int32_t UsWinDescent();
+    void SetUsWinDescent(int32_t descent);
+    int64_t UlCodePageRange1();
+    void SetUlCodePageRange1(int64_t range);
+    int64_t UlCodePageRange2();
+    void SetUlCodePageRange2(int64_t range);
+    // UNIMPLEMENTED: EnumSet<CodePageRange> ulCodePageRange()
+    //                void setUlCodePageRange(EnumSet<CodePageRange> rangeSet)
+    int32_t SxHeight();
+    void SetSxHeight(int32_t height);
+    int32_t SCapHeight();
+    void SetSCapHeight(int32_t height);
+    int32_t UsDefaultChar();
+    void SetUsDefaultChar(int32_t default_char);
+    int32_t UsBreakChar();
+    void SetUsBreakChar(int32_t break_char);
+    int32_t UsMaxContext();
+    void SetUsMaxContext(int32_t max_context);
+  };
+
+  ~OS2Table();
+
+  int32_t TableVersion();
+  int32_t XAvgCharWidth();
+  int32_t UsWeightClass();
+  int32_t UsWidthClass();
+  // UNIMPLEMENTED: public EnumSet<EmbeddingFlags> fsType()
+  int32_t FsType();
+  int32_t YSubscriptXSize();
+  int32_t YSubscriptYSize();
+  int32_t YSubscriptXOffset();
+  int32_t YSubscriptYOffset();
+  int32_t YSuperscriptXSize();
+  int32_t YSuperscriptYSize();
+  int32_t YSuperscriptXOffset();
+  int32_t YSuperscriptYOffset();
+  int32_t YStrikeoutSize();
+  int32_t YStrikeoutPosition();
+  int32_t SFamilyClass();
+  void Panose(ByteVector* value);
+  int64_t UlUnicodeRange1();
+  int64_t UlUnicodeRange2();
+  int64_t UlUnicodeRange3();
+  int64_t UlUnicodeRange4();
+  // UNIMPLEMENTED: public EnumSet<UnicodeRange> UlUnicodeRange()
+  void AchVendId(ByteVector* b);
+  // UNIMPLEMENTED: public EnumSet<FsSelection> fsSelection()
+  int32_t FsSelection();
+  int32_t UsFirstCharIndex();
+  int32_t UsLastCharIndex();
+  int32_t STypoAscender();
+  int32_t STypoDescender();
+  int32_t STypoLineGap();
+  int32_t UsWinAscent();
+  int32_t UsWinDescent();
+  int64_t UlCodePageRange1();
+  int64_t UlCodePageRange2();
+  // UNIMPLEMENTED: public EnumSet<CodePageRange> ulCodePageRange()
+  int32_t SxHeight();
+  int32_t SCapHeight();
+  int32_t UsDefaultChar();
+  int32_t UsBreakChar();
+  int32_t UsMaxContext();
+
+ private:
+  struct Offset {
+    enum {
+      kVersion = 0,
+      kXAvgCharWidth = 2,
+      kUsWeightClass = 4,
+      kUsWidthClass = 6,
+      kFsType = 8,
+      kYSubscriptXSize = 10,
+      kYSubscriptYSize = 12,
+      kYSubscriptXOffset = 14,
+      kYSubscriptYOffset = 16,
+      kYSuperscriptXSize = 18,
+      kYSuperscriptYSize = 20,
+      kYSuperscriptXOffset = 22,
+      kYSuperscriptYOffset = 24,
+      kYStrikeoutSize = 26,
+      kYStrikeoutPosition = 28,
+      kSFamilyClass = 30,
+      kPanose = 32,
+      kPanoseLength = 10,  // Length of panose bytes.
+      kUlUnicodeRange1 = 42,
+      kUlUnicodeRange2 = 46,
+      kUlUnicodeRange3 = 50,
+      kUlUnicodeRange4 = 54,
+      kAchVendId = 58,
+      kAchVendIdLength = 4,  // Length of ach vend id bytes.
+      kFsSelection = 62,
+      kUsFirstCharIndex = 64,
+      kUsLastCharIndex = 66,
+      kSTypoAscender = 68,
+      kSTypoDescender = 70,
+      kSTypoLineGap = 72,
+      kUsWinAscent = 74,
+      kUsWinDescent = 76,
+      kUlCodePageRange1 = 78,
+      kUlCodePageRange2 = 82,
+      kSxHeight = 86,
+      kSCapHeight = 88,
+      kUsDefaultChar = 90,
+      kUsBreakChar = 92,
+      kUsMaxContext = 94
+    };
+  };
+
+  OS2Table(Header* header, ReadableFontData* data);
+};
+typedef Ptr<OS2Table> OS2TablePtr;
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_OS2_TABLE_H_
diff --git a/sfntly/table/font_data_table.cc b/sfntly/table/font_data_table.cc
new file mode 100644
index 0000000..0e27f7a
--- /dev/null
+++ b/sfntly/table/font_data_table.cc
@@ -0,0 +1,193 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/table/font_data_table.h"
+
+#include "sfntly/data/font_output_stream.h"
+
+namespace sfntly {
+
+/******************************************************************************
+ * FontDataTable class
+ ******************************************************************************/
+
+FontDataTable::FontDataTable(ReadableFontData* data) {
+  data_ = data;
+}
+
+FontDataTable::~FontDataTable() {}
+
+ReadableFontData* FontDataTable::ReadFontData() {
+  return data_;
+}
+
+int32_t FontDataTable::DataLength() {
+  return data_->Length();
+}
+
+int32_t FontDataTable::Serialize(OutputStream* os) {
+  return data_->CopyTo(os);
+}
+
+int32_t FontDataTable::Serialize(WritableFontData* data) {
+  return data_->CopyTo(data);
+}
+
+/******************************************************************************
+ * FontDataTable::Builder class
+ ******************************************************************************/
+CALLER_ATTACH WritableFontData* FontDataTable::Builder::Data() {
+  WritableFontDataPtr new_data;
+  if (model_changed_) {
+    if (!SubReadyToSerialize()) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+      throw IOException("Table not ready to build.");
+#endif
+      return NULL;
+    }
+    int32_t size = SubDataSizeToSerialize();
+    new_data.Attach(WritableFontData::CreateWritableFontData(size));
+    SubSerialize(new_data);
+  } else {
+    ReadableFontDataPtr data = InternalReadData();
+    new_data.Attach(WritableFontData::CreateWritableFontData(
+                        data != NULL ? data->Length() : 0));
+    if (data != NULL) {
+      data->CopyTo(new_data);
+    }
+  }
+  return new_data.Detach();
+}
+
+void FontDataTable::Builder::SetData(ReadableFontData* data) {
+  InternalSetData(data, true);
+}
+
+
+CALLER_ATTACH FontDataTable* FontDataTable::Builder::Build() {
+  FontDataTablePtr table;  // NULL default table
+  ReadableFontDataPtr data = InternalReadData();
+  if (model_changed_) {
+    // Let subclass serialize from model.
+    if (!SubReadyToSerialize()) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+      throw IOException("Table not ready to build.");
+#endif
+      return NULL;
+    }
+    int32_t size = SubDataSizeToSerialize();
+    WritableFontDataPtr new_data;
+    new_data.Attach(WritableFontData::CreateWritableFontData(size));
+    SubSerialize(new_data);
+    data = new_data;
+  }
+
+  if (data != NULL) {
+    table = SubBuildTable(data);
+    NotifyPostTableBuild(table);
+  }
+
+  r_data_.Release();
+  w_data_.Release();
+  return table;
+}
+
+bool FontDataTable::Builder::ReadyToBuild() {
+  return true;
+}
+
+ReadableFontData* FontDataTable::Builder::InternalReadData() {
+  return (r_data_ != NULL) ? r_data_.p_ :
+                             static_cast<ReadableFontData*>(w_data_.p_);
+}
+
+WritableFontData* FontDataTable::Builder::InternalWriteData() {
+  if (w_data_ == NULL) {
+    WritableFontDataPtr new_data;
+    new_data.Attach(WritableFontData::CreateWritableFontData(
+                        r_data_ == NULL ? 0 : r_data_->Length()));
+#if !defined (SFNTLY_NO_EXCEPTION)
+    try {
+#endif
+      if (r_data_) {
+        r_data_->CopyTo(new_data);
+      }
+#if !defined (SFNTLY_NO_EXCEPTION)
+    } catch (IOException& e) {
+      // TODO(stuartg): fix when IOExceptions are cleaned up
+    }
+#endif
+    InternalSetData(new_data, false);
+  }
+  return w_data_.p_;
+}
+
+FontDataTable::Builder::Builder()
+    : model_changed_(false),
+      contained_model_changed_(false),
+      data_changed_(false) {
+}
+
+FontDataTable::Builder::Builder(int32_t data_size)
+    : model_changed_(false),
+      contained_model_changed_(false),
+      data_changed_(false) {
+  w_data_.Attach(WritableFontData::CreateWritableFontData(data_size));
+}
+
+FontDataTable::Builder::Builder(WritableFontData* data)
+    : model_changed_(false),
+      contained_model_changed_(false),
+      data_changed_(false) {
+  w_data_ = data;
+}
+
+FontDataTable::Builder::Builder(ReadableFontData* data)
+    : model_changed_(false),
+      contained_model_changed_(false),
+      data_changed_(false) {
+  r_data_ = data;
+}
+
+FontDataTable::Builder::~Builder() {
+}
+
+void FontDataTable::Builder::NotifyPostTableBuild(FontDataTable* table) {
+  // Default: NOP.
+  UNREFERENCED_PARAMETER(table);
+}
+
+void FontDataTable::Builder::InternalSetData(WritableFontData* data,
+                                             bool data_changed) {
+  w_data_ = data;
+  r_data_ = NULL;
+  if (data_changed) {
+    data_changed_ = true;
+    SubDataSet();
+  }
+}
+
+void FontDataTable::Builder::InternalSetData(ReadableFontData* data,
+                                             bool data_changed) {
+  w_data_ = NULL;
+  r_data_ = data;
+  if (data_changed) {
+    data_changed_ = true;
+    SubDataSet();
+  }
+}
+
+}  // namespace sfntly
diff --git a/sfntly/table/font_data_table.h b/sfntly/table/font_data_table.h
new file mode 100644
index 0000000..5e437e2
--- /dev/null
+++ b/sfntly/table/font_data_table.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_FONT_DATA_TABLE_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_FONT_DATA_TABLE_H_
+
+#include "sfntly/data/readable_font_data.h"
+#include "sfntly/data/writable_font_data.h"
+#include "sfntly/port/refcount.h"
+
+namespace sfntly {
+
+// An abstract base for any table that contains a FontData. This is the root of
+// the table class hierarchy.
+class FontDataTable : virtual public RefCount {
+ public:
+  // Note: original version is abstract Builder<T extends FontDataTable>
+  //       C++ template is not designed that way so plain class is chosen.
+  class Builder : virtual public RefCount {
+   public:
+    // Get a snapshot copy of the internal data of the builder.
+    // This causes any internal data structures to be serialized to a new data
+    // object. This data object belongs to the caller and must be properly
+    // disposed of. No changes are made to the builder and any changes to the
+    // data directly do not affect the internal state. To do that a subsequent
+    // call must be made to {@link #SetData(WritableFontData)}.
+    // @return a copy of the internal data of the builder
+    CALLER_ATTACH WritableFontData* Data();
+    virtual void SetData(ReadableFontData* data);
+
+    // Note: changed from protected to avoid accessibility error in C++
+    virtual CALLER_ATTACH FontDataTable* Build();
+    virtual bool ReadyToBuild();
+
+    ReadableFontData* InternalReadData();
+    WritableFontData* InternalWriteData();
+
+    bool data_changed() { return data_changed_; }
+    bool model_changed() {
+      return current_model_changed() || contained_model_changed();
+    }
+    bool current_model_changed() { return model_changed_; }
+    bool contained_model_changed() { return contained_model_changed_; }
+
+    bool set_model_changed() { return set_model_changed(true); }
+    bool set_model_changed(bool changed) {
+      bool old = model_changed_;
+      model_changed_ = changed;
+      return old;
+    }
+
+   protected:
+    explicit Builder();
+
+    // Construct a FontDataTable.Builder with a WritableFontData backing store
+    // of size given. A positive size will create a fixed size backing store and
+    // a 0 or less size is an estimate for a growable backing store with the
+    // estimate being the absolute of the size.
+    // @param dataSize if positive then a fixed size; if 0 or less then an
+    //        estimate for a growable size
+    Builder(int32_t data_size);
+    Builder(WritableFontData* data);
+    Builder(ReadableFontData* data);
+    virtual ~Builder();
+
+    // subclass API
+    virtual void NotifyPostTableBuild(FontDataTable* table);
+    virtual int32_t SubSerialize(WritableFontData* new_data) = 0;
+    virtual bool SubReadyToSerialize() = 0;
+    virtual int32_t SubDataSizeToSerialize() = 0;
+    virtual void SubDataSet() = 0;
+    virtual CALLER_ATTACH FontDataTable*
+        SubBuildTable(ReadableFontData* data) = 0;
+
+   private:
+    void InternalSetData(WritableFontData* data, bool data_changed);
+    void InternalSetData(ReadableFontData* data, bool data_changed);
+
+    WritableFontDataPtr w_data_;
+    ReadableFontDataPtr r_data_;
+    bool model_changed_;
+    bool contained_model_changed_;  // may expand to list of submodel states
+    bool data_changed_;
+  };
+
+  explicit FontDataTable(ReadableFontData* data);
+  virtual ~FontDataTable();
+
+  // Get the readable font data for this table.
+  ReadableFontData* ReadFontData();
+
+  // Get the length of the data for this table in bytes. This is the full
+  // allocated length of the data underlying the table and may or may not
+  // include any padding.
+  virtual int32_t DataLength();
+
+  virtual int32_t Serialize(OutputStream* os);
+
+ protected:
+  virtual int32_t Serialize(WritableFontData* data);
+
+  // TODO(arthurhsu): style guide violation: protected member, need refactoring
+  ReadableFontDataPtr data_;
+};
+typedef Ptr<FontDataTable> FontDataTablePtr;
+typedef Ptr<FontDataTable::Builder> FontDataTableBuilderPtr;
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_FONT_DATA_TABLE_H_
diff --git a/sfntly/table/generic_table_builder.cc b/sfntly/table/generic_table_builder.cc
new file mode 100644
index 0000000..78e6797
--- /dev/null
+++ b/sfntly/table/generic_table_builder.cc
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/table/generic_table_builder.h"
+
+namespace sfntly {
+
+GenericTableBuilder::~GenericTableBuilder() {}
+
+CALLER_ATTACH
+FontDataTable* GenericTableBuilder::SubBuildTable(ReadableFontData* data) {
+  // Note: In C++ port, we use GenericTable, the ref-counted version of Table
+  UNREFERENCED_PARAMETER(data);
+  Ptr<GenericTable> table = new GenericTable(header(), InternalReadData());
+  return table.Detach();
+}
+
+// static
+CALLER_ATTACH GenericTableBuilder*
+    GenericTableBuilder::CreateBuilder(Header* header, WritableFontData* data) {
+  Ptr<GenericTableBuilder> builder =
+      new GenericTableBuilder(header, data);
+  return builder.Detach();
+}
+
+GenericTableBuilder::GenericTableBuilder(Header* header,
+                                         WritableFontData* data)
+    : TableBasedTableBuilder(header, data) {
+}
+
+GenericTableBuilder::GenericTableBuilder(Header* header,
+                                         ReadableFontData* data)
+    : TableBasedTableBuilder(header, data) {
+}
+
+}  // namespace sfntly
diff --git a/sfntly/table/generic_table_builder.h b/sfntly/table/generic_table_builder.h
new file mode 100644
index 0000000..a100ea0
--- /dev/null
+++ b/sfntly/table/generic_table_builder.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_GENERIC_TABLE_BUILDER_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_GENERIC_TABLE_BUILDER_H_
+
+#include "sfntly/table/table_based_table_builder.h"
+
+namespace sfntly {
+
+// A table builder to do the minimal table building for an unknown table type.
+class GenericTableBuilder : public TableBasedTableBuilder,
+                            public RefCounted<GenericTableBuilder> {
+ public:
+  virtual ~GenericTableBuilder();
+
+  virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+
+  static CALLER_ATTACH GenericTableBuilder*
+      CreateBuilder(Header* header, WritableFontData* data);
+
+ private:
+  GenericTableBuilder(Header* header, WritableFontData* data);
+  GenericTableBuilder(Header* header, ReadableFontData* data);
+};
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_BYTE_ARRAY_TABLE_BUILDER_H_
diff --git a/sfntly/table/header.cc b/sfntly/table/header.cc
new file mode 100644
index 0000000..672ace5
--- /dev/null
+++ b/sfntly/table/header.cc
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/table/header.h"
+
+namespace sfntly {
+
+/******************************************************************************
+ * Header class
+ ******************************************************************************/
+Header::Header(int32_t tag)
+    : tag_(tag),
+      offset_(0),
+      offset_valid_(false),
+      length_(0),
+      length_valid_(false),
+      checksum_(0),
+      checksum_valid_(false) {
+}
+
+Header::Header(int32_t tag, int32_t length)
+    : tag_(tag),
+      offset_(0),
+      offset_valid_(false),
+      length_(length),
+      length_valid_(true),
+      checksum_(0),
+      checksum_valid_(false) {
+}
+
+Header::Header(int32_t tag, int64_t checksum, int32_t offset, int32_t length)
+    : tag_(tag),
+      offset_(offset),
+      offset_valid_(true),
+      length_(length),
+      length_valid_(true),
+      checksum_(checksum),
+      checksum_valid_(true) {
+}
+
+Header::~Header() {}
+
+bool HeaderComparatorByOffset::operator() (const HeaderPtr lhs,
+                                           const HeaderPtr rhs) {
+  return lhs->offset_ > rhs->offset_;
+}
+
+bool HeaderComparatorByTag::operator() (const HeaderPtr lhs,
+                                        const HeaderPtr rhs) {
+  return lhs->tag_ > rhs->tag_;
+}
+
+}  // namespace sfntly
diff --git a/sfntly/table/header.h b/sfntly/table/header.h
new file mode 100644
index 0000000..280e556
--- /dev/null
+++ b/sfntly/table/header.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_HEADER_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_HEADER_H_
+
+#include "sfntly/port/refcount.h"
+
+namespace sfntly {
+
+class Header : public RefCounted<Header> {
+ public:
+  // Make a partial header with only the basic info for an empty new table.
+  explicit Header(int32_t tag);
+
+  // Make a partial header with only the basic info for a new table.
+  Header(int32_t tag, int32_t length);
+
+  // Make a full header as read from an existing font.
+  Header(int32_t tag, int64_t checksum, int32_t offset, int32_t length);
+  virtual ~Header();
+
+  // Get the table tag.
+  int32_t tag() { return tag_; }
+
+  // Get the table offset. The offset is from the start of the font file.  This
+  // offset value is what was read from the font file during construction of the
+  // font. It may not be meaningful if the font was maninpulated through the
+  // builders.
+  int32_t offset() { return offset_; }
+
+  // Is the offset in the header valid. The offset will not be valid if the
+  // table was constructed during building and has no physical location in a
+  // font file.
+  bool offset_valid() { return offset_valid_; }
+
+  // Get the length of the table as recorded in the table record header.  During
+  // building the header length will reflect the length that was initially read
+  // from the font file. This may not be consistent with the current state of
+  // the data.
+  int32_t length() { return length_; }
+
+  // Is the length in the header valid. The length will not be valid if the
+  // table was constructed during building and has no physical location in a
+  // font file until the table is built from the builder.
+  bool length_valid() { return length_valid_; }
+
+  // Get the checksum for the table as recorded in the table record header.
+  int64_t checksum() { return checksum_; }
+
+  // Is the checksum valid. The checksum will not be valid if the table was
+  // constructed during building and has no physical location in a font file.
+  // Note that this does *NOT* check the validity of the checksum against
+  // the calculated checksum for the table data.
+  bool checksum_valid() { return checksum_valid_; }
+
+  // UNIMPLEMENTED: boolean equals(Object obj)
+  //                int hashCode()
+  //                string toString()
+
+ private:
+  int32_t tag_;
+  int32_t offset_;
+  bool offset_valid_;
+  int32_t length_;
+  bool length_valid_;
+  int64_t checksum_;
+  bool checksum_valid_;
+
+  friend class HeaderComparatorByOffset;
+  friend class HeaderComparatorByTag;
+};
+typedef Ptr<Header> HeaderPtr;
+
+class HeaderComparator {
+ public:
+  virtual ~HeaderComparator() {}
+  virtual bool operator()(const HeaderPtr h1,
+                          const HeaderPtr h2) = 0;
+};
+
+class HeaderComparatorByOffset : public HeaderComparator {
+ public:
+  virtual ~HeaderComparatorByOffset() {}
+  virtual bool operator()(const HeaderPtr h1,
+                          const HeaderPtr h2);
+};
+
+class HeaderComparatorByTag : public HeaderComparator {
+ public:
+  virtual ~HeaderComparatorByTag() {}
+  virtual bool operator()(const HeaderPtr h1,
+                          const HeaderPtr h2);
+};
+
+typedef std::set<HeaderPtr, HeaderComparatorByOffset> HeaderOffsetSortedSet;
+typedef std::set<HeaderPtr, HeaderComparatorByTag> HeaderTagSortedSet;
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_HEADER_H_
diff --git a/sfntly/table/subtable.cc b/sfntly/table/subtable.cc
new file mode 100644
index 0000000..e5b906f
--- /dev/null
+++ b/sfntly/table/subtable.cc
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/table/subtable.h"
+
+namespace sfntly {
+/******************************************************************************
+ * SubTable class
+ ******************************************************************************/
+SubTable::~SubTable() {}
+
+SubTable::SubTable(ReadableFontData* data, ReadableFontData* master_data)
+    : FontDataTable(data), padding_(0) {
+  master_data_ = master_data;
+}
+
+SubTable::SubTable(ReadableFontData* data)
+    : FontDataTable(data), padding_(0) {
+}
+
+/******************************************************************************
+ * SubTable::Builder class
+ ******************************************************************************/
+SubTable::Builder::~Builder() {
+}
+
+SubTable::Builder::Builder(int32_t data_size)
+    : FontDataTable::Builder(data_size) {
+}
+
+SubTable::Builder::Builder(WritableFontData* data,
+                           ReadableFontData* master_data)
+    : FontDataTable::Builder(data) {
+  master_data_ = master_data;
+}
+
+SubTable::Builder::Builder(ReadableFontData* data,
+                           ReadableFontData* master_data)
+    : FontDataTable::Builder(data) {
+  master_data_ = master_data;
+}
+
+SubTable::Builder::Builder(WritableFontData* data)
+    : FontDataTable::Builder(data) {
+}
+
+SubTable::Builder::Builder(ReadableFontData* data)
+    : FontDataTable::Builder(data) {
+}
+
+}  // namespace sfntly
diff --git a/sfntly/table/subtable.h b/sfntly/table/subtable.h
new file mode 100644
index 0000000..fa6f4c6
--- /dev/null
+++ b/sfntly/table/subtable.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_SUBTABLE_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_SUBTABLE_H_
+
+#include "sfntly/table/font_data_table.h"
+
+namespace sfntly {
+
+// An abstract base class for subtables. Subtables are smaller tables nested
+// within other tables and don't have an entry in the main font index. Examples
+// of these are the CMap subtables within CMap table (cmap) or a glyph within
+// the glyph table (glyf).
+class SubTable : public FontDataTable {
+ public:
+  class Builder : public FontDataTable::Builder {
+   public:
+    virtual ~Builder();
+
+   protected:
+    // @param data the data for the subtable being built
+    // @param master_data the data for the full table
+    Builder(int32_t data_size);
+    Builder(WritableFontData* data, ReadableFontData* master_data);
+    Builder(ReadableFontData* data, ReadableFontData* master_data);
+    explicit Builder(WritableFontData* data);
+    explicit Builder(ReadableFontData* data);
+
+    ReadableFontData* master_read_data() { return master_data_; }
+
+   private:
+    ReadableFontDataPtr master_data_;
+  };
+
+  virtual ~SubTable();
+  virtual int32_t Padding() { return padding_; }
+
+  // Sets the amount of padding that is part of the data being used by this
+  // subtable.
+  void set_padding(int32_t padding) { padding_ = padding; }
+
+ protected:
+  SubTable(ReadableFontData* data, ReadableFontData* master_data);
+
+  // Note: constructor refactored in C++ to avoid heavy lifting.
+  //       caller need to do data->Slice(offset, length) beforehand.
+  explicit SubTable(ReadableFontData* data);
+
+  ReadableFontData* master_read_data() { return master_data_; }
+
+ private:
+  // The data for the whole table in which this subtable is contained.
+  ReadableFontDataPtr master_data_;
+  int32_t padding_;
+};
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_SUBTABLE_H_
diff --git a/sfntly/table/subtable_container_table.h b/sfntly/table/subtable_container_table.h
new file mode 100644
index 0000000..0f099de
--- /dev/null
+++ b/sfntly/table/subtable_container_table.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef TYPOGRAPHY_FONT_SFNTLY_SRC_SFNTLY_TABLE_SUBTABLE_CONTAINER_TABLE_H_
+#define TYPOGRAPHY_FONT_SFNTLY_SRC_SFNTLY_TABLE_SUBTABLE_CONTAINER_TABLE_H_
+
+#include "sfntly/table/table.h"
+
+namespace sfntly {
+
+class SubTableContainerTable : public Table {
+ public:
+  class Builder : public Table::Builder {
+   public:
+    Builder(Header* header, WritableFontData* data)
+        : Table::Builder(header, data) {
+    }
+
+    Builder(Header* header, ReadableFontData* data)
+        : Table::Builder(header, data) {
+    }
+
+    virtual ~Builder() {}
+  };
+
+  SubTableContainerTable(Header* header, ReadableFontData* data)
+      : Table(header, data) {
+  }
+
+  virtual ~SubTableContainerTable() {}
+};
+
+}  // namespace sfntly
+
+#endif  // TYPOGRAPHY_FONT_SFNTLY_SRC_SFNTLY_TABLE_SUBTABLE_CONTAINER_TABLE_H_
diff --git a/sfntly/table/table.cc b/sfntly/table/table.cc
new file mode 100644
index 0000000..cf574b8
--- /dev/null
+++ b/sfntly/table/table.cc
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+// type.h needs to be included first because of building issues on Windows
+// Type aliases we delcare are defined in other headers and make the build
+// fail otherwise.
+#include "sfntly/port/type.h"
+#include "sfntly/table/table.h"
+
+#include "sfntly/font.h"
+#include "sfntly/tag.h"
+#include "sfntly/table/bitmap/ebdt_table.h"
+#include "sfntly/table/bitmap/eblc_table.h"
+#include "sfntly/table/bitmap/ebsc_table.h"
+#include "sfntly/table/core/cmap_table.h"
+#include "sfntly/table/core/font_header_table.h"
+#include "sfntly/table/core/horizontal_device_metrics_table.h"
+#include "sfntly/table/core/horizontal_header_table.h"
+#include "sfntly/table/core/horizontal_metrics_table.h"
+#include "sfntly/table/core/maximum_profile_table.h"
+#include "sfntly/table/core/name_table.h"
+#include "sfntly/table/core/os2_table.h"
+#include "sfntly/table/generic_table_builder.h"
+#include "sfntly/table/table_based_table_builder.h"
+#include "sfntly/table/truetype/glyph_table.h"
+#include "sfntly/table/truetype/loca_table.h"
+
+namespace sfntly {
+
+/******************************************************************************
+ * Table class
+ ******************************************************************************/
+Table::~Table() {}
+
+int64_t Table::CalculatedChecksum() {
+  return data_->Checksum();
+}
+
+void Table::SetFont(Font* font) {
+  font_ = font;
+}
+
+Table::Table(Header* header, ReadableFontData* data)
+    : FontDataTable(data) {
+  header_ = header;
+}
+
+/******************************************************************************
+ * Table::Builder class
+ ******************************************************************************/
+Table::Builder::~Builder() {
+  header_.Release();
+}
+
+void Table::Builder::NotifyPostTableBuild(FontDataTable* table) {
+  if (model_changed() || data_changed()) {
+    Table* derived_table = down_cast<Table*>(table);
+    derived_table->header_ = new Header(header()->tag(),
+                                        derived_table->DataLength());
+  }
+}
+
+CALLER_ATTACH
+Table::Builder* Table::Builder::GetBuilder(Header* header,
+                                           WritableFontData* table_data) {
+  int32_t tag = header->tag();
+  Table::Builder* builder_raw = NULL;
+
+  // Note: Tables are commented out when they are not used/ported.
+  // TODO(arthurhsu): IMPLEMENT: finish tables that are not ported.
+  if (tag == Tag::head) {
+    builder_raw = static_cast<Table::Builder*>(
+        FontHeaderTable::Builder::CreateBuilder(header, table_data));
+#if defined (SFNTLY_EXPERIMENTAL)
+  } else if (tag == Tag::cmap) {
+    builder_raw = static_cast<Table::Builder*>(
+        CMapTable::Builder::CreateBuilder(header, table_data));
+#endif  // SFNTLY_EXPERIMENTAL
+  } else if (tag == Tag::hhea) {
+    builder_raw = static_cast<Table::Builder*>(
+        HorizontalHeaderTable::Builder::CreateBuilder(header, table_data));
+  } else if (tag == Tag::hmtx) {
+    builder_raw = static_cast<Table::Builder*>(
+        HorizontalMetricsTable::Builder::CreateBuilder(header, table_data));
+  } else if (tag == Tag::maxp) {
+    builder_raw = static_cast<Table::Builder*>(
+        MaximumProfileTable::Builder::CreateBuilder(header, table_data));
+  } else if (tag == Tag::name) {
+    builder_raw = static_cast<Table::Builder*>(
+        NameTable::Builder::CreateBuilder(header, table_data));
+  } else if (tag == Tag::OS_2) {
+    builder_raw = static_cast<Table::Builder*>(
+        OS2Table::Builder::CreateBuilder(header, table_data));
+  }/* else if (tag == Tag::PostScript) {
+    builder_raw = static_cast<Table::Builder*>(
+        PostScriptTable::Builder::CreateBuilder(header, table_data));
+  } else if (tag == Tag::cvt) {
+    builder_raw = static_cast<Table::Builder*>(
+        ControlValueTable::Builder::CreateBuilder(header, table_data));
+  }*/ else if (tag == Tag::glyf) {
+    builder_raw = static_cast<Table::Builder*>(
+        GlyphTable::Builder::CreateBuilder(header, table_data));
+  } else if (tag == Tag::loca) {
+    builder_raw = static_cast<Table::Builder*>(
+        LocaTable::Builder::CreateBuilder(header, table_data));
+  } else if (tag == Tag::EBDT || tag == Tag::bdat) {
+    builder_raw = static_cast<Table::Builder*>(
+        EbdtTable::Builder::CreateBuilder(header, table_data));
+  } else if (tag == Tag::EBLC || tag == Tag::bloc) {
+    builder_raw = static_cast<Table::Builder*>(
+        EblcTable::Builder::CreateBuilder(header, table_data));
+  } else if (tag == Tag::EBSC) {
+    builder_raw = static_cast<Table::Builder*>(
+        EbscTable::Builder::CreateBuilder(header, table_data));
+  } /* else if (tag == Tag::prep) {
+    builder_raw = static_cast<Table::Builder*>(
+        ControlProgramTable::Builder::CreateBuilder(header, table_data));
+  }*/ else if (tag == Tag::bhed) {
+    builder_raw = static_cast<Table::Builder*>(
+        FontHeaderTable::Builder::CreateBuilder(header, table_data));
+#if defined (SFNTLY_EXPERIMENTAL)
+  } else if (tag == Tag::hdmx) {
+    builder_raw = static_cast<Table::Builder*>(
+        HorizontalDeviceMetricsTable::Builder::CreateBuilder(header,
+                                                             table_data));
+#endif  // SFNTLY_EXPERIMENTAL
+  } else {
+    builder_raw = static_cast<Table::Builder*>(
+        GenericTableBuilder::CreateBuilder(header, table_data));
+  }
+
+  return builder_raw;
+}
+
+Table::Builder::Builder(Header* header, WritableFontData* data)
+    : FontDataTable::Builder(data) {
+  header_ = header;
+}
+
+Table::Builder::Builder(Header* header, ReadableFontData* data)
+    : FontDataTable::Builder(data) {
+  header_ = header;
+}
+
+Table::Builder::Builder(Header* header) {
+  header_ = header;
+}
+
+}  // namespace sfntly
diff --git a/sfntly/table/table.h b/sfntly/table/table.h
new file mode 100644
index 0000000..6ebc22d
--- /dev/null
+++ b/sfntly/table/table.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_TABLE_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_TABLE_H_
+
+#include <set>
+#include <map>
+#include <vector>
+#include <utility>
+
+#include "sfntly/port/type.h"
+#include "sfntly/table/font_data_table.h"
+#include "sfntly/table/header.h"
+
+namespace sfntly {
+class Font;
+
+// A concrete implementation of a root level table in the font. This is the base
+// class used for all specific table implementations and is used as the generic
+// table for all tables which have no specific implementations.
+class Table : public FontDataTable {
+ public:
+  // Note: original version is Builder<T extends Table>
+  //       C++ template is not designed that way so plain old inheritance is
+  //       chosen.
+  class Builder : public FontDataTable::Builder {
+   public:
+    virtual ~Builder();
+    virtual Header* header() { return header_; }
+    virtual void NotifyPostTableBuild(FontDataTable* table);
+
+    // Get a builder for the table type specified by the data in the header.
+    // @param header the header for the table
+    // @param tableData the data to be used to build the table from
+    // @return builder for the table specified
+    static CALLER_ATTACH Builder* GetBuilder(Header* header,
+                                             WritableFontData* table_data);
+
+    // UNIMPLEMENTED: toString()
+
+   protected:
+    Builder(Header* header, WritableFontData* data);
+    Builder(Header* header, ReadableFontData* data);
+    Builder(Header* header);
+
+   private:
+    Ptr<Header> header_;
+  };
+
+  // Note: GenericTableBuilder moved to table_based_table_builder.h to avoid
+  //       circular inclusion.
+
+  virtual ~Table();
+
+  // Get the calculated checksum for the data in the table.
+  virtual int64_t CalculatedChecksum();
+
+  // Get the header for the table.
+  virtual Header* header()          { return header_; }
+
+  // Get the tag for the table from the record header.
+  virtual int32_t header_tag()      { return header_->tag(); }
+
+  // Get the offset for the table from the record header.
+  virtual int32_t header_offset()   { return header_->offset(); }
+
+  // Get the length of the table from the record header.
+  virtual int32_t header_length()   { return header_->length(); }
+
+  // Get the checksum for the table from the record header.
+  virtual int64_t header_checksum() { return header_->checksum(); }
+
+  // UNIMPLEMENTED: toString()
+
+  virtual void SetFont(Font* font);
+
+ protected:
+  Table(Header* header, ReadableFontData* data);
+
+ private:
+  Ptr<Header> header_;
+  Ptr<Font> font_;
+};
+
+// C++ port only
+class GenericTable : public Table, public RefCounted<GenericTable> {
+ public:
+  GenericTable(Header* header, ReadableFontData* data) : Table(header, data) {}
+  virtual ~GenericTable() {}
+};
+
+typedef Ptr<Table> TablePtr;
+typedef std::vector<HeaderPtr> TableHeaderList;
+typedef Ptr<Table::Builder> TableBuilderPtr;
+typedef std::map<int32_t, TablePtr> TableMap;
+typedef std::pair<int32_t, TablePtr> TableMapEntry;
+
+typedef std::map<HeaderPtr, WritableFontDataPtr> DataBlockMap;
+typedef std::pair<HeaderPtr, WritableFontDataPtr> DataBlockEntry;
+typedef std::map<int32_t, TableBuilderPtr> TableBuilderMap;
+typedef std::pair<int32_t, TableBuilderPtr> TableBuilderEntry;
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_TABLE_H_
diff --git a/sfntly/table/table_based_table_builder.cc b/sfntly/table/table_based_table_builder.cc
new file mode 100644
index 0000000..b505704
--- /dev/null
+++ b/sfntly/table/table_based_table_builder.cc
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/table/table_based_table_builder.h"
+
+namespace sfntly {
+
+/******************************************************************************
+ * TableBasedTableBuilder class
+ ******************************************************************************/
+TableBasedTableBuilder::~TableBasedTableBuilder() {}
+
+int32_t TableBasedTableBuilder::SubSerialize(WritableFontData* data) {
+  UNREFERENCED_PARAMETER(data);
+  return 0;
+}
+
+bool TableBasedTableBuilder::SubReadyToSerialize() {
+  return false;
+}
+
+int32_t TableBasedTableBuilder::SubDataSizeToSerialize() {
+  return 0;
+}
+
+void TableBasedTableBuilder::SubDataSet() {
+  table_ = NULL;
+}
+
+CALLER_ATTACH FontDataTable* TableBasedTableBuilder::Build() {
+  FontDataTablePtr table = static_cast<FontDataTable*>(GetTable());
+  return table.Detach();
+}
+
+TableBasedTableBuilder::TableBasedTableBuilder(Header* header,
+                                               WritableFontData* data)
+    : Table::Builder(header, data) {
+}
+
+TableBasedTableBuilder::TableBasedTableBuilder(Header* header,
+                                               ReadableFontData* data)
+    : Table::Builder(header, data) {
+}
+
+TableBasedTableBuilder::TableBasedTableBuilder(Header* header)
+    : Table::Builder(header) {
+}
+
+Table* TableBasedTableBuilder::GetTable() {
+  if (table_ == NULL) {
+    table_.Attach(down_cast<Table*>(SubBuildTable(InternalReadData())));
+  }
+  return table_;
+}
+
+}  // namespace sfntly
diff --git a/sfntly/table/table_based_table_builder.h b/sfntly/table/table_based_table_builder.h
new file mode 100644
index 0000000..d88eefd
--- /dev/null
+++ b/sfntly/table/table_based_table_builder.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_TABLE_BASED_TABLE_BUILDER_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_TABLE_BASED_TABLE_BUILDER_H_
+
+#include "sfntly/table/table.h"
+
+namespace sfntly {
+
+class TableBasedTableBuilder : public Table::Builder {
+ public:
+  virtual ~TableBasedTableBuilder();
+
+  virtual int32_t SubSerialize(WritableFontData* new_data);
+  virtual bool SubReadyToSerialize();
+  virtual int32_t SubDataSizeToSerialize();
+  virtual void SubDataSet();
+  virtual CALLER_ATTACH FontDataTable* Build();
+
+ protected:
+  TableBasedTableBuilder(Header* header, WritableFontData* data);
+  TableBasedTableBuilder(Header* header, ReadableFontData* data);
+  explicit TableBasedTableBuilder(Header* header);
+
+  // C++ port: renamed table() to GetTable()
+  virtual Table* GetTable();
+
+  // TODO(arthurhsu): style guide violation: protected member, need refactor
+  TablePtr table_;
+};
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_TABLE_BASED_TABLE_BUILDER_H_
diff --git a/sfntly/table/truetype/glyph_table.cc b/sfntly/table/truetype/glyph_table.cc
new file mode 100644
index 0000000..f38fac5
--- /dev/null
+++ b/sfntly/table/truetype/glyph_table.cc
@@ -0,0 +1,679 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/table/truetype/glyph_table.h"
+
+#include <stdlib.h>
+
+#include "sfntly/port/exception_type.h"
+
+namespace sfntly {
+/******************************************************************************
+ * Constants
+ ******************************************************************************/
+const int32_t GlyphTable::SimpleGlyph::kFLAG_ONCURVE = 1;
+const int32_t GlyphTable::SimpleGlyph::kFLAG_XSHORT = 1 << 1;
+const int32_t GlyphTable::SimpleGlyph::kFLAG_YSHORT = 1 << 2;
+const int32_t GlyphTable::SimpleGlyph::kFLAG_REPEAT = 1 << 3;
+const int32_t GlyphTable::SimpleGlyph::kFLAG_XREPEATSIGN = 1 << 4;
+const int32_t GlyphTable::SimpleGlyph::kFLAG_YREPEATSIGN = 1 << 5;
+
+const int32_t GlyphTable::CompositeGlyph::kFLAG_ARG_1_AND_2_ARE_WORDS = 1 << 0;
+const int32_t GlyphTable::CompositeGlyph::kFLAG_ARGS_ARE_XY_VALUES = 1 << 1;
+const int32_t GlyphTable::CompositeGlyph::kFLAG_ROUND_XY_TO_GRID = 1 << 2;
+const int32_t GlyphTable::CompositeGlyph::kFLAG_WE_HAVE_A_SCALE = 1 << 3;
+const int32_t GlyphTable::CompositeGlyph::kFLAG_RESERVED = 1 << 4;
+const int32_t GlyphTable::CompositeGlyph::kFLAG_MORE_COMPONENTS = 1 << 5;
+const int32_t GlyphTable::CompositeGlyph::kFLAG_WE_HAVE_AN_X_AND_Y_SCALE = 1 << 6;
+const int32_t GlyphTable::CompositeGlyph::kFLAG_WE_HAVE_A_TWO_BY_TWO = 1 << 7;
+const int32_t GlyphTable::CompositeGlyph::kFLAG_WE_HAVE_INSTRUCTIONS = 1 << 8;
+const int32_t GlyphTable::CompositeGlyph::kFLAG_USE_MY_METRICS = 1 << 9;
+const int32_t GlyphTable::CompositeGlyph::kFLAG_OVERLAP_COMPOUND = 1 << 10;
+const int32_t GlyphTable::CompositeGlyph::kFLAG_SCALED_COMPONENT_OFFSET = 1 << 11;
+const int32_t GlyphTable::CompositeGlyph::kFLAG_UNSCALED_COMPONENT_OFFSET = 1 << 12;
+
+/******************************************************************************
+ * GlyphTable class
+ ******************************************************************************/
+GlyphTable::~GlyphTable() {
+}
+
+GlyphTable::Glyph* GlyphTable::GetGlyph(int32_t offset, int32_t length) {
+  return GlyphTable::Glyph::GetGlyph(this, this->data_, offset, length);
+}
+
+GlyphTable::GlyphTable(Header* header, ReadableFontData* data)
+    : SubTableContainerTable(header, data) {
+}
+
+/******************************************************************************
+ * GlyphTable::Builder class
+ ******************************************************************************/
+GlyphTable::Builder::Builder(Header* header, ReadableFontData* data)
+    : SubTableContainerTable::Builder(header, data) {
+}
+
+GlyphTable::Builder::~Builder() {
+}
+
+void GlyphTable::Builder::SetLoca(const IntegerList& loca) {
+  loca_ = loca;
+  set_model_changed(false);
+  glyph_builders_.clear();
+}
+
+void GlyphTable::Builder::GenerateLocaList(IntegerList* locas) {
+  assert(locas);
+  GlyphBuilderList* glyph_builders = GetGlyphBuilders();
+  locas->push_back(0);
+  if (glyph_builders->size() == 0) {
+    locas->push_back(0);
+  } else {
+    int32_t total = 0;
+    for (GlyphBuilderList::iterator b = glyph_builders->begin(),
+                                    b_end = glyph_builders->end();
+                                    b != b_end; ++b) {
+      int32_t size = (*b)->SubDataSizeToSerialize();
+      locas->push_back(total + size);
+      total += size;
+    }
+  }
+}
+
+CALLER_ATTACH GlyphTable::Builder*
+    GlyphTable::Builder::CreateBuilder(Header* header, WritableFontData* data) {
+  Ptr<GlyphTable::Builder> builder;
+  builder = new GlyphTable::Builder(header, data);
+  return builder.Detach();
+}
+
+GlyphTable::GlyphBuilderList* GlyphTable::Builder::GlyphBuilders() {
+  return GetGlyphBuilders();
+}
+
+void GlyphTable::Builder::SetGlyphBuilders(GlyphBuilderList* glyph_builders) {
+  glyph_builders_ = *glyph_builders;
+  set_model_changed();
+}
+
+CALLER_ATTACH GlyphTable::Glyph::Builder*
+    GlyphTable::Builder::GlyphBuilder(ReadableFontData* data) {
+  return Glyph::Builder::GetBuilder(this, data);
+}
+
+CALLER_ATTACH FontDataTable*
+    GlyphTable::Builder::SubBuildTable(ReadableFontData* data) {
+  FontDataTablePtr table = new GlyphTable(header(), data);
+  return table.Detach();
+}
+
+void GlyphTable::Builder::SubDataSet() {
+  glyph_builders_.clear();
+  set_model_changed(false);
+}
+
+int32_t GlyphTable::Builder::SubDataSizeToSerialize() {
+  if (glyph_builders_.empty())
+    return 0;
+
+  bool variable = false;
+  int32_t size = 0;
+
+  // Calculate size of each table.
+  for (GlyphBuilderList::iterator b = glyph_builders_.begin(),
+                                  end = glyph_builders_.end(); b != end; ++b) {
+      int32_t glyph_size = (*b)->SubDataSizeToSerialize();
+      size += abs(glyph_size);
+      variable |= glyph_size <= 0;
+  }
+  return variable ? -size : size;
+}
+
+bool GlyphTable::Builder::SubReadyToSerialize() {
+  return !glyph_builders_.empty();
+}
+
+int32_t GlyphTable::Builder::SubSerialize(WritableFontData* new_data) {
+  int32_t size = 0;
+  for (GlyphBuilderList::iterator b = glyph_builders_.begin(),
+                                  end = glyph_builders_.end(); b != end; ++b) {
+    FontDataPtr data;
+    data.Attach(new_data->Slice(size));
+    size += (*b)->SubSerialize(down_cast<WritableFontData*>(data.p_));
+  }
+  return size;
+}
+
+void GlyphTable::Builder::Initialize(ReadableFontData* data,
+                                     const IntegerList& loca) {
+  if (data != NULL) {
+    if (loca_.empty()) {
+      return;
+    }
+    int32_t loca_value;
+    int32_t last_loca_value = loca[0];
+    for (size_t i = 1; i < loca.size(); ++i) {
+      loca_value = loca[i];
+      GlyphBuilderPtr builder;
+      builder.Attach(
+        Glyph::Builder::GetBuilder(this,
+                                   data,
+                                   last_loca_value /*offset*/,
+                                   loca_value - last_loca_value /*length*/));
+      glyph_builders_.push_back(builder);
+      last_loca_value = loca_value;
+    }
+  }
+}
+
+GlyphTable::GlyphBuilderList* GlyphTable::Builder::GetGlyphBuilders() {
+  if (glyph_builders_.empty()) {
+    if (InternalReadData() && !loca_.empty()) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+      throw IllegalStateException(
+          "Loca values not set - unable to parse glyph data.");
+#endif
+      return NULL;
+    }
+    Initialize(InternalReadData(), loca_);
+    set_model_changed();
+  }
+  return &glyph_builders_;
+}
+
+void GlyphTable::Builder::Revert() {
+  glyph_builders_.clear();
+  set_model_changed(false);
+}
+
+/******************************************************************************
+ * GlyphTable::Glyph class
+ ******************************************************************************/
+GlyphTable::Glyph::~Glyph() {}
+
+CALLER_ATTACH GlyphTable::Glyph*
+    GlyphTable::Glyph::GetGlyph(GlyphTable* table,
+                                ReadableFontData* data,
+                                int32_t offset,
+                                int32_t length) {
+  UNREFERENCED_PARAMETER(table);
+  int32_t type = GlyphType(data, offset, length);
+  GlyphPtr glyph;
+
+  ReadableFontDataPtr sliced_data;
+  sliced_data.Attach(down_cast<ReadableFontData*>(data->Slice(offset, length)));
+  if (type == GlyphType::kSimple) {
+    glyph = new SimpleGlyph(sliced_data);
+  } else {
+    glyph = new CompositeGlyph(sliced_data);
+  }
+  return glyph.Detach();
+}
+
+int32_t GlyphTable::Glyph::Padding() {
+  Initialize();
+  return SubTable::Padding();
+}
+
+int32_t GlyphTable::Glyph::GlyphType() {
+  return glyph_type_;
+}
+
+int32_t GlyphTable::Glyph::NumberOfContours() {
+  return number_of_contours_;
+}
+
+int32_t GlyphTable::Glyph::XMin() {
+  return data_->ReadShort(Offset::kXMin);
+}
+
+int32_t GlyphTable::Glyph::XMax() {
+  return data_->ReadShort(Offset::kXMax);
+}
+
+int32_t GlyphTable::Glyph::YMin() {
+  return data_->ReadShort(Offset::kYMin);
+}
+
+int32_t GlyphTable::Glyph::YMax() {
+  return data_->ReadShort(Offset::kYMax);
+}
+
+GlyphTable::Glyph::Glyph(ReadableFontData* data, int32_t glyph_type)
+    : SubTable(data),
+      glyph_type_(glyph_type) {
+  if (data_->Length() == 0) {
+    number_of_contours_ = 0;
+  } else {
+    // -1 if composite
+    number_of_contours_ = data_->ReadShort(Offset::kNumberOfContours);
+  }
+}
+
+int32_t GlyphTable::Glyph::GlyphType(ReadableFontData* data,
+                                     int32_t offset,
+                                     int32_t length) {
+  if (length == 0) {
+    return GlyphType::kSimple;
+  }
+  int32_t number_of_contours = data->ReadShort(offset);
+  if (number_of_contours >= 0) {
+    return GlyphType::kSimple;
+  }
+  return GlyphType::kComposite;
+}
+
+/******************************************************************************
+ * GlyphTable::Glyph::Builder class
+ ******************************************************************************/
+GlyphTable::Glyph::Builder::~Builder() {
+}
+
+GlyphTable::Glyph::Builder::Builder(WritableFontData* data)
+    : SubTable::Builder(data) {
+}
+
+GlyphTable::Glyph::Builder::Builder(ReadableFontData* data)
+    : SubTable::Builder(data) {
+}
+
+CALLER_ATTACH GlyphTable::Glyph::Builder*
+    GlyphTable::Glyph::Builder::GetBuilder(
+        GlyphTable::Builder* table_builder,
+        ReadableFontData* data) {
+  return GetBuilder(table_builder, data, 0, data->Length());
+}
+
+CALLER_ATTACH GlyphTable::Glyph::Builder*
+    GlyphTable::Glyph::Builder::GetBuilder(
+        GlyphTable::Builder* table_builder,
+        ReadableFontData* data,
+        int32_t offset,
+        int32_t length) {
+  UNREFERENCED_PARAMETER(table_builder);
+  int32_t type = Glyph::GlyphType(data, offset, length);
+  GlyphBuilderPtr builder;
+  ReadableFontDataPtr sliced_data;
+  sliced_data.Attach(down_cast<ReadableFontData*>(data->Slice(offset, length)));
+  if (type == GlyphType::kSimple) {
+    builder = new SimpleGlyph::SimpleGlyphBuilder(sliced_data);
+  } else {
+    builder = new CompositeGlyph::CompositeGlyphBuilder(sliced_data);
+  }
+  return builder.Detach();
+}
+
+void GlyphTable::Glyph::Builder::SubDataSet() {
+  // NOP
+}
+
+int32_t GlyphTable::Glyph::Builder::SubDataSizeToSerialize() {
+  return InternalReadData()->Length();
+}
+
+bool GlyphTable::Glyph::Builder::SubReadyToSerialize() {
+  return true;
+}
+
+int32_t GlyphTable::Glyph::Builder::SubSerialize(WritableFontData* new_data) {
+  return InternalReadData()->CopyTo(new_data);
+}
+
+/******************************************************************************
+ * GlyphTable::SimpleGlyph
+ ******************************************************************************/
+GlyphTable::SimpleGlyph::SimpleGlyph(ReadableFontData* data)
+    : GlyphTable::Glyph(data, GlyphType::kSimple), initialized_(false) {
+}
+
+GlyphTable::SimpleGlyph::~SimpleGlyph() {
+}
+
+int32_t GlyphTable::SimpleGlyph::InstructionSize() {
+  Initialize();
+  return instruction_size_;
+}
+
+CALLER_ATTACH ReadableFontData* GlyphTable::SimpleGlyph::Instructions() {
+  Initialize();
+  return down_cast<ReadableFontData*>(
+             data_->Slice(instructions_offset_, InstructionSize()));
+}
+
+int32_t GlyphTable::SimpleGlyph::NumberOfPoints(int32_t contour) {
+  Initialize();
+  if (contour >= NumberOfContours()) {
+    return 0;
+  }
+  return contour_index_[contour + 1] - contour_index_[contour];
+}
+
+int32_t GlyphTable::SimpleGlyph::XCoordinate(int32_t contour, int32_t point) {
+  Initialize();
+  return x_coordinates_[contour_index_[contour] + point];
+}
+
+int32_t GlyphTable::SimpleGlyph::YCoordinate(int32_t contour, int32_t point) {
+  Initialize();
+  return y_coordinates_[contour_index_[contour] + point];
+}
+
+bool GlyphTable::SimpleGlyph::OnCurve(int32_t contour, int32_t point) {
+  Initialize();
+  return on_curve_[contour_index_[contour] + point];
+}
+
+void GlyphTable::SimpleGlyph::Initialize() {
+  AutoLock lock(initialization_lock_);
+  if (initialized_) {
+    return;
+  }
+
+  if (ReadFontData()->Length() == 0) {
+    instruction_size_ = 0;
+    number_of_points_ = 0;
+    instructions_offset_ = 0;
+    flags_offset_ = 0;
+    x_coordinates_offset_ = 0;
+    y_coordinates_offset_ = 0;
+    return;
+  }
+
+  instruction_size_ = data_->ReadUShort(Offset::kSimpleEndPtsOfCountours +
+      NumberOfContours() * DataSize::kUSHORT);
+  instructions_offset_ = Offset::kSimpleEndPtsOfCountours +
+      (NumberOfContours() + 1) * DataSize::kUSHORT;
+  flags_offset_ = instructions_offset_ + instruction_size_ * DataSize::kBYTE;
+  number_of_points_ = ContourEndPoint(NumberOfContours() - 1) + 1;
+  x_coordinates_.resize(number_of_points_);
+  y_coordinates_.resize(number_of_points_);
+  on_curve_.resize(number_of_points_);
+  ParseData(false);
+  x_coordinates_offset_ = flags_offset_ + flag_byte_count_ * DataSize::kBYTE;
+  y_coordinates_offset_ = x_coordinates_offset_ + x_byte_count_ *
+      DataSize::kBYTE;
+  contour_index_.resize(NumberOfContours() + 1);
+  contour_index_[0] = 0;
+  for (uint32_t contour = 0; contour < contour_index_.size() - 1; ++contour) {
+    contour_index_[contour + 1] = ContourEndPoint(contour) + 1;
+  }
+  ParseData(true);
+  int32_t non_padded_data_length =
+    5 * DataSize::kSHORT +
+    (NumberOfContours() * DataSize::kUSHORT) +
+    DataSize::kUSHORT +
+    (instruction_size_ * DataSize::kBYTE) +
+    (flag_byte_count_ * DataSize::kBYTE) +
+    (x_byte_count_ * DataSize::kBYTE) +
+    (y_byte_count_ * DataSize::kBYTE);
+  set_padding(DataLength() - non_padded_data_length);
+  initialized_ = true;
+}
+
+void GlyphTable::SimpleGlyph::ParseData(bool fill_arrays) {
+  int32_t flag = 0;
+  int32_t flag_repeat = 0;
+  int32_t flag_index = 0;
+  int32_t x_byte_index = 0;
+  int32_t y_byte_index = 0;
+
+  for (int32_t point_index = 0; point_index < number_of_points_;
+       ++point_index) {
+    // get the flag for the current point
+    if (flag_repeat == 0) {
+      flag = FlagAsInt(flag_index++);
+      if ((flag & kFLAG_REPEAT) == kFLAG_REPEAT) {
+        flag_repeat = FlagAsInt(flag_index++);
+      }
+    } else {
+      flag_repeat--;
+    }
+
+    // on the curve?
+    if (fill_arrays) {
+      on_curve_[point_index] = ((flag & kFLAG_ONCURVE) == kFLAG_ONCURVE);
+    }
+    // get the x coordinate
+    if ((flag & kFLAG_XSHORT) == kFLAG_XSHORT) {
+      // single byte x coord value
+      if (fill_arrays) {
+        x_coordinates_[point_index] =
+            data_->ReadUByte(x_coordinates_offset_ + x_byte_index);
+        x_coordinates_[point_index] *=
+            ((flag & kFLAG_XREPEATSIGN) == kFLAG_XREPEATSIGN) ? 1 : -1;
+      }
+      x_byte_index++;
+    } else {
+      // double byte coord value
+      if (!((flag & kFLAG_XREPEATSIGN) == kFLAG_XREPEATSIGN)) {
+        if (fill_arrays) {
+          x_coordinates_[point_index] =
+            data_->ReadShort(x_coordinates_offset_ + x_byte_index);
+        }
+        x_byte_index += 2;
+      }
+    }
+    if (fill_arrays && point_index > 0) {
+      x_coordinates_[point_index] += x_coordinates_[point_index - 1];
+    }
+
+    // get the y coordinate
+    if ((flag & kFLAG_YSHORT) == kFLAG_YSHORT) {
+      if (fill_arrays) {
+        y_coordinates_[point_index] =
+          data_->ReadUByte(y_coordinates_offset_ + y_byte_index);
+        y_coordinates_[point_index] *=
+          ((flag & kFLAG_YREPEATSIGN) == kFLAG_YREPEATSIGN) ? 1 : -1;
+      }
+      y_byte_index++;
+    } else {
+      if (!((flag & kFLAG_YREPEATSIGN) == kFLAG_YREPEATSIGN)) {
+        if (fill_arrays) {
+          y_coordinates_[point_index] =
+            data_->ReadShort(y_coordinates_offset_ + y_byte_index);
+        }
+        y_byte_index += 2;
+      }
+    }
+    if (fill_arrays && point_index > 0) {
+      y_coordinates_[point_index] += y_coordinates_[point_index - 1];
+    }
+  }
+  flag_byte_count_ = flag_index;
+  x_byte_count_ = x_byte_index;
+  y_byte_count_ = y_byte_index;
+}
+
+int32_t GlyphTable::SimpleGlyph::FlagAsInt(int32_t index) {
+  return data_->ReadUByte(flags_offset_ + index * DataSize::kBYTE);
+}
+
+int32_t GlyphTable::SimpleGlyph::ContourEndPoint(int32_t contour) {
+  return data_->ReadUShort(contour * DataSize::kUSHORT +
+                           Offset::kSimpleEndPtsOfCountours);
+}
+
+/******************************************************************************
+ * GlyphTable::SimpleGlyph::Builder
+ ******************************************************************************/
+GlyphTable::SimpleGlyph::SimpleGlyphBuilder::~SimpleGlyphBuilder() {
+}
+
+GlyphTable::SimpleGlyph::SimpleGlyphBuilder::SimpleGlyphBuilder(
+    WritableFontData* data)
+    : Glyph::Builder(data) {
+}
+
+GlyphTable::SimpleGlyph::SimpleGlyphBuilder::SimpleGlyphBuilder(
+    ReadableFontData* data)
+    : Glyph::Builder(data) {
+}
+
+CALLER_ATTACH FontDataTable*
+    GlyphTable::SimpleGlyph::SimpleGlyphBuilder::SubBuildTable(
+        ReadableFontData* data) {
+  FontDataTablePtr table = new SimpleGlyph(data);
+  return table.Detach();
+}
+
+/******************************************************************************
+ * GlyphTable::CompositeGlyph
+ ******************************************************************************/
+GlyphTable::CompositeGlyph::CompositeGlyph(ReadableFontData* data)
+    : GlyphTable::Glyph(data, GlyphType::kComposite),
+      instruction_size_(0),
+      instructions_offset_(0),
+      initialized_(false) {
+  Initialize();
+}
+
+GlyphTable::CompositeGlyph::~CompositeGlyph() {
+}
+
+int32_t GlyphTable::CompositeGlyph::Flags(int32_t contour) {
+  return data_->ReadUShort(contour_index_[contour]);
+}
+
+int32_t GlyphTable::CompositeGlyph::NumGlyphs() {
+  return contour_index_.size();
+}
+
+int32_t GlyphTable::CompositeGlyph::GlyphIndex(int32_t contour) {
+  return data_->ReadUShort(DataSize::kUSHORT + contour_index_[contour]);
+}
+
+int32_t GlyphTable::CompositeGlyph::Argument1(int32_t contour) {
+  int32_t index = 2 * DataSize::kUSHORT + contour_index_[contour];
+  int32_t contour_flags = Flags(contour);
+  if ((contour_flags & kFLAG_ARG_1_AND_2_ARE_WORDS) ==
+                       kFLAG_ARG_1_AND_2_ARE_WORDS) {
+    return data_->ReadUShort(index);
+  }
+  return data_->ReadByte(index);
+}
+
+int32_t GlyphTable::CompositeGlyph::Argument2(int32_t contour) {
+  int32_t index = 2 * DataSize::kUSHORT + contour_index_[contour];
+  int32_t contour_flags = Flags(contour);
+  if ((contour_flags & kFLAG_ARG_1_AND_2_ARE_WORDS) ==
+                       kFLAG_ARG_1_AND_2_ARE_WORDS) {
+    return data_->ReadUShort(index + DataSize::kUSHORT);
+  }
+  return data_->ReadByte(index + DataSize::kUSHORT);
+}
+
+int32_t GlyphTable::CompositeGlyph::TransformationSize(int32_t contour) {
+  int32_t contour_flags = Flags(contour);
+  if ((contour_flags & kFLAG_WE_HAVE_A_SCALE) == kFLAG_WE_HAVE_A_SCALE) {
+      return DataSize::kF2DOT14;
+    } else if ((contour_flags & kFLAG_WE_HAVE_AN_X_AND_Y_SCALE) ==
+                                kFLAG_WE_HAVE_AN_X_AND_Y_SCALE) {
+      return 2 * DataSize::kF2DOT14;
+    } else if ((contour_flags & kFLAG_WE_HAVE_A_TWO_BY_TWO) ==
+                                kFLAG_WE_HAVE_A_TWO_BY_TWO) {
+      return 4 * DataSize::kF2DOT14;
+    }
+    return 0;
+}
+
+void GlyphTable::CompositeGlyph::Transformation(int32_t contour,
+                                                ByteVector* transformation) {
+  int32_t contour_flags = Flags(contour);
+  int32_t index = contour_index_[contour] + 2 * DataSize::kUSHORT;
+  if ((contour_flags & kFLAG_ARG_1_AND_2_ARE_WORDS) ==
+                       kFLAG_ARG_1_AND_2_ARE_WORDS) {
+    index += 2 * DataSize::kSHORT;
+  } else {
+    index += 2 * DataSize::kBYTE;
+  }
+  int32_t tsize = TransformationSize(contour);
+  transformation->resize(tsize);
+  data_->ReadBytes(index, &((*transformation)[0]), 0, tsize);
+}
+
+int32_t GlyphTable::CompositeGlyph::InstructionSize() {
+  return instruction_size_;
+}
+
+CALLER_ATTACH ReadableFontData* GlyphTable::CompositeGlyph::Instructions() {
+  return down_cast<ReadableFontData*>(
+             data_->Slice(instructions_offset_, InstructionSize()));
+}
+
+void GlyphTable::CompositeGlyph::Initialize() {
+  AutoLock lock(initialization_lock_);
+  if (initialized_) {
+    return;
+  }
+
+  int32_t index = 5 * DataSize::kUSHORT;
+  int32_t flags = kFLAG_MORE_COMPONENTS;
+
+  while ((flags & kFLAG_MORE_COMPONENTS) == kFLAG_MORE_COMPONENTS) {
+    contour_index_.push_back(index);
+    flags = data_->ReadUShort(index);
+    index += 2 * DataSize::kUSHORT;  // flags and glyphIndex
+    if ((flags & kFLAG_ARG_1_AND_2_ARE_WORDS) == kFLAG_ARG_1_AND_2_ARE_WORDS) {
+      index += 2 * DataSize::kSHORT;
+    } else {
+      index += 2 * DataSize::kBYTE;
+    }
+    if ((flags & kFLAG_WE_HAVE_A_SCALE) == kFLAG_WE_HAVE_A_SCALE) {
+      index += DataSize::kF2DOT14;
+    } else if ((flags & kFLAG_WE_HAVE_AN_X_AND_Y_SCALE) ==
+                        kFLAG_WE_HAVE_AN_X_AND_Y_SCALE) {
+      index += 2 * DataSize::kF2DOT14;
+    } else if ((flags & kFLAG_WE_HAVE_A_TWO_BY_TWO) ==
+                        kFLAG_WE_HAVE_A_TWO_BY_TWO) {
+      index += 4 * DataSize::kF2DOT14;
+    }
+    int32_t non_padded_data_length = index;
+    if ((flags & kFLAG_WE_HAVE_INSTRUCTIONS) == kFLAG_WE_HAVE_INSTRUCTIONS) {
+      instruction_size_ = data_->ReadUShort(index);
+      index += DataSize::kUSHORT;
+      instructions_offset_ = index;
+      non_padded_data_length = index + (instruction_size_ * DataSize::kBYTE);
+    }
+    set_padding(DataLength() - non_padded_data_length);
+  }
+
+  initialized_ = true;
+}
+
+/******************************************************************************
+ * GlyphTable::CompositeGlyph::Builder
+ ******************************************************************************/
+GlyphTable::CompositeGlyph::CompositeGlyphBuilder::~CompositeGlyphBuilder() {
+}
+
+GlyphTable::CompositeGlyph::CompositeGlyphBuilder::CompositeGlyphBuilder(
+    WritableFontData* data)
+    : Glyph::Builder(data) {
+}
+
+GlyphTable::CompositeGlyph::CompositeGlyphBuilder::CompositeGlyphBuilder(
+    ReadableFontData* data)
+    : Glyph::Builder(data) {
+}
+
+CALLER_ATTACH FontDataTable*
+    GlyphTable::CompositeGlyph::CompositeGlyphBuilder::SubBuildTable(
+        ReadableFontData* data) {
+  FontDataTablePtr table = new CompositeGlyph(data);
+  return table.Detach();
+}
+
+}  // namespace sfntly
diff --git a/sfntly/table/truetype/glyph_table.h b/sfntly/table/truetype/glyph_table.h
new file mode 100644
index 0000000..4ffddda
--- /dev/null
+++ b/sfntly/table/truetype/glyph_table.h
@@ -0,0 +1,334 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_TRUETYPE_GLYPH_TABLE_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_TRUETYPE_GLYPH_TABLE_H_
+
+#include <vector>
+
+#include "sfntly/table/table.h"
+#include "sfntly/table/subtable.h"
+#include "sfntly/table/subtable_container_table.h"
+
+namespace sfntly {
+
+struct GlyphType {
+  enum {
+    kSimple = 0,
+    kComposite = 1
+  };
+};
+
+class GlyphTable : public SubTableContainerTable,
+                   public RefCounted<GlyphTable> {
+ public:
+  class Builder;
+  class Glyph : public SubTable {
+   public:
+    // Note: Contour is an empty class for the version ported
+    class Contour {
+     protected:
+      Contour() {}
+      virtual ~Contour() {}
+    };
+
+    class Builder : public SubTable::Builder {
+     public:
+      virtual ~Builder();
+
+     protected:
+      // Incoming table_builder is GlyphTable::Builder*.
+      // Note: constructor refactored in C++ to avoid heavy lifting.
+      //       caller need to do data->Slice(offset, length) beforehand.
+      explicit Builder(WritableFontData* data);
+      explicit Builder(ReadableFontData* data);
+
+      static CALLER_ATTACH Builder*
+          GetBuilder(GlyphTable::Builder* table_builder,
+                     ReadableFontData* data);
+      static CALLER_ATTACH Builder*
+          GetBuilder(GlyphTable::Builder* table_builder,
+                     ReadableFontData* data,
+                     int32_t offset,
+                     int32_t length);
+      virtual void SubDataSet();
+      virtual int32_t SubDataSizeToSerialize();
+      virtual bool SubReadyToSerialize();
+      virtual int32_t SubSerialize(WritableFontData* new_data);
+
+     private:
+      friend class GlyphTable::Builder;
+    };
+
+    virtual ~Glyph();
+    static CALLER_ATTACH Glyph* GetGlyph(GlyphTable* table,
+                                         ReadableFontData* data,
+                                         int32_t offset,
+                                         int32_t length);
+
+    virtual int32_t Padding();
+    virtual int32_t GlyphType();
+    virtual int32_t NumberOfContours();
+    virtual int32_t XMin();
+    virtual int32_t XMax();
+    virtual int32_t YMin();
+    virtual int32_t YMax();
+
+    virtual int32_t InstructionSize() = 0;
+    virtual ReadableFontData* Instructions() = 0;
+
+   protected:
+    // Note: constructor refactored in C++ to avoid heavy lifting.
+    //       caller need to do data->Slice(offset, length) beforehand.
+    Glyph(ReadableFontData* data, int32_t glyph_type);
+    virtual void Initialize() = 0;
+    // Note: Derived class to define initialization_lock_.
+
+   private:
+    static int32_t GlyphType(ReadableFontData* data,
+                             int32_t offset,
+                             int32_t length);
+
+    int32_t glyph_type_;
+    int32_t number_of_contours_;
+  };  // class GlyphTable::Glyph
+  typedef Ptr<GlyphTable::Glyph::Builder> GlyphBuilderPtr;
+  typedef std::vector<GlyphBuilderPtr> GlyphBuilderList;
+
+  class Builder : public SubTableContainerTable::Builder,
+                  public RefCounted<GlyphTable::Builder> {
+   public:
+    // Note: Constructor scope altered to public for base class to instantiate.
+    Builder(Header* header, ReadableFontData* data);
+    virtual ~Builder();
+
+    virtual void SetLoca(const IntegerList& loca);
+    virtual void GenerateLocaList(IntegerList* locas);
+
+    static CALLER_ATTACH Builder* CreateBuilder(Header* header,
+                                                WritableFontData* data);
+
+    // Gets the List of glyph builders for the glyph table builder. These may be
+    // manipulated in any way by the caller and the changes will be reflected in
+    // the final glyph table produced.
+    // If there is no current data for the glyph builder or the glyph builders
+    // have not been previously set then this will return an empty glyph builder
+    // List. If there is current data (i.e. data read from an existing font) and
+    // the <code>loca</code> list has not been set or is null, empty, or
+    // invalid, then an empty glyph builder List will be returned.
+    GlyphBuilderList* GlyphBuilders();
+
+    // Replace the internal glyph builders with the one provided. The provided
+    // list and all contained objects belong to this builder.
+    // This call is only required if the entire set of glyphs in the glyph
+    // table builder are being replaced. If the glyph builder list provided from
+    // the GlyphTable.Builder::GlyphBuilders() is being used and modified
+    // then those changes will already be reflected in the glyph table builder.
+    void SetGlyphBuilders(GlyphBuilderList* glyph_builders);
+
+    // Glyph builder factories
+    CALLER_ATTACH Glyph::Builder* GlyphBuilder(ReadableFontData* data);
+
+   protected:  // internal API for building
+    virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+    virtual void SubDataSet();
+    virtual int32_t SubDataSizeToSerialize();
+    virtual bool SubReadyToSerialize();
+    virtual int32_t SubSerialize(WritableFontData* new_data);
+
+   private:
+    void Initialize(ReadableFontData* data, const IntegerList& loca);
+    GlyphBuilderList* GetGlyphBuilders();
+    void Revert();
+
+    GlyphBuilderList glyph_builders_;
+    IntegerList loca_;
+  };
+
+  class SimpleGlyph : public Glyph, public RefCounted<SimpleGlyph> {
+   public:
+    static const int32_t kFLAG_ONCURVE;
+    static const int32_t kFLAG_XSHORT;
+    static const int32_t kFLAG_YSHORT;
+    static const int32_t kFLAG_REPEAT;
+    static const int32_t kFLAG_XREPEATSIGN;
+    static const int32_t kFLAG_YREPEATSIGN;
+
+    class SimpleContour : public Glyph::Contour {
+     protected:
+      SimpleContour() {}
+      virtual ~SimpleContour() {}
+    };
+
+    class SimpleGlyphBuilder : public Glyph::Builder,
+                               public RefCounted<SimpleGlyphBuilder> {
+     public:
+      virtual ~SimpleGlyphBuilder();
+
+     protected:
+      // Note: constructor refactored in C++ to avoid heavy lifting.
+      //       caller need to do data->Slice(offset, length) beforehand.
+      explicit SimpleGlyphBuilder(WritableFontData* data);
+      explicit SimpleGlyphBuilder(ReadableFontData* data);
+      virtual CALLER_ATTACH FontDataTable*
+          SubBuildTable(ReadableFontData* data);
+
+     private:
+      friend class Glyph::Builder;
+    };
+
+    // Note: constructor refactored in C++ to avoid heavy lifting.
+    //       caller need to do data->Slice(offset, length) beforehand.
+    explicit SimpleGlyph(ReadableFontData* data);
+    virtual ~SimpleGlyph();
+
+    virtual int32_t InstructionSize();
+    virtual CALLER_ATTACH ReadableFontData* Instructions();
+    virtual void Initialize();
+
+    int32_t NumberOfPoints(int32_t contour);
+    int32_t XCoordinate(int32_t contour, int32_t point);
+    int32_t YCoordinate(int32_t contour, int32_t point);
+    bool OnCurve(int32_t contour, int32_t point);
+
+   private:
+    void ParseData(bool fill_arrays);
+    int32_t FlagAsInt(int32_t index);
+    int32_t ContourEndPoint(int32_t contour);
+
+    bool initialized_;
+    Lock initialization_lock_;
+    int32_t instruction_size_;
+    int32_t number_of_points_;
+
+    // start offsets of the arrays
+    int32_t instructions_offset_;
+    int32_t flags_offset_;
+    int32_t x_coordinates_offset_;
+    int32_t y_coordinates_offset_;
+
+    int32_t flag_byte_count_;
+    int32_t x_byte_count_;
+    int32_t y_byte_count_;
+
+    IntegerList x_coordinates_;
+    IntegerList y_coordinates_;
+    std::vector<bool> on_curve_;
+    IntegerList contour_index_;
+  };
+
+  class CompositeGlyph : public Glyph, public RefCounted<CompositeGlyph> {
+   public:
+    static const int32_t kFLAG_ARG_1_AND_2_ARE_WORDS;
+    static const int32_t kFLAG_ARGS_ARE_XY_VALUES;
+    static const int32_t kFLAG_ROUND_XY_TO_GRID;
+    static const int32_t kFLAG_WE_HAVE_A_SCALE;
+    static const int32_t kFLAG_RESERVED;
+    static const int32_t kFLAG_MORE_COMPONENTS;
+    static const int32_t kFLAG_WE_HAVE_AN_X_AND_Y_SCALE;
+    static const int32_t kFLAG_WE_HAVE_A_TWO_BY_TWO;
+    static const int32_t kFLAG_WE_HAVE_INSTRUCTIONS;
+    static const int32_t kFLAG_USE_MY_METRICS;
+    static const int32_t kFLAG_OVERLAP_COMPOUND;
+    static const int32_t kFLAG_SCALED_COMPONENT_OFFSET;
+    static const int32_t kFLAG_UNSCALED_COMPONENT_OFFSET;
+
+    class CompositeGlyphBuilder : public Glyph::Builder,
+                                  public RefCounted<CompositeGlyphBuilder> {
+     public:
+      virtual ~CompositeGlyphBuilder();
+
+     protected:
+      // Note: constructor refactored in C++ to avoid heavy lifting.
+      //       caller need to do data->Slice(offset, length) beforehand.
+      explicit CompositeGlyphBuilder(WritableFontData* data);
+      explicit CompositeGlyphBuilder(ReadableFontData* data);
+
+      virtual CALLER_ATTACH FontDataTable*
+          SubBuildTable(ReadableFontData* data);
+
+     private:
+      friend class Glyph::Builder;
+    };
+
+    // Note: constructor refactored in C++ to avoid heavy lifting.
+    //       caller need to do data->Slice(offset, length) beforehand.
+    explicit CompositeGlyph(ReadableFontData* data);
+    virtual ~CompositeGlyph();
+
+    int32_t Flags(int32_t contour);
+    int32_t NumGlyphs();
+    int32_t GlyphIndex(int32_t contour);
+    int32_t Argument1(int32_t contour);
+    int32_t Argument2(int32_t contour);
+    int32_t TransformationSize(int32_t contour);
+    void Transformation(int32_t contour, ByteVector* transformation);
+    virtual int32_t InstructionSize();
+    virtual CALLER_ATTACH ReadableFontData* Instructions();
+
+   protected:
+    virtual void Initialize();
+
+   private:
+    IntegerList contour_index_;
+    int32_t instruction_size_;
+    int32_t instructions_offset_;
+    bool initialized_;
+    Lock initialization_lock_;
+  };
+
+  virtual ~GlyphTable();
+
+  // C++ port: rename glyph() to GetGlyph().
+  Glyph* GetGlyph(int32_t offset, int32_t length);
+
+ private:
+  struct Offset {
+    enum {
+      // header
+      kNumberOfContours = 0,
+      kXMin = 2,
+      kYMin = 4,
+      kXMax = 6,
+      kYMax = 8,
+
+      // Simple Glyph Description
+      kSimpleEndPtsOfCountours = 10,
+      // offset from the end of the contours array
+      kSimpleInstructionLength = 0,
+      kSimpleInstructions = 2,
+      // flags
+      // xCoordinates
+      // yCoordinates
+
+      // Composite Glyph Description
+      kCompositeFlags = 0,
+      kCompositeGyphIndexWithoutFlag = 0,
+      kCompositeGlyphIndexWithFlag = 2,
+    };
+  };
+
+  GlyphTable(Header* header, ReadableFontData* data);
+};
+typedef Ptr<GlyphTable> GlyphTablePtr;
+typedef Ptr<GlyphTable::Builder> GlyphTableBuilderPtr;
+typedef std::vector<GlyphTableBuilderPtr> GlyphTableBuilderList;
+typedef Ptr<GlyphTable::Glyph> GlyphPtr;
+typedef Ptr<GlyphTable::Glyph::Builder> GlyphBuilderPtr;
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_TRUETYPE_GLYPH_TABLE_H_
diff --git a/sfntly/table/truetype/loca_table.cc b/sfntly/table/truetype/loca_table.cc
new file mode 100644
index 0000000..c692155
--- /dev/null
+++ b/sfntly/table/truetype/loca_table.cc
@@ -0,0 +1,246 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/table/truetype/loca_table.h"
+#include "sfntly/port/exception_type.h"
+
+namespace sfntly {
+/******************************************************************************
+ * LocaTable class
+ ******************************************************************************/
+LocaTable::~LocaTable() {}
+
+int32_t LocaTable::GlyphOffset(int32_t glyph_id) {
+  if (glyph_id < 0 || glyph_id >= num_glyphs_) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IndexOutOfBoundException("Glyph ID is out of bounds.");
+#endif
+    return 0;
+  }
+  return Loca(glyph_id);
+}
+
+int32_t LocaTable::GlyphLength(int32_t glyph_id) {
+  if (glyph_id < 0 || glyph_id >= num_glyphs_) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IndexOutOfBoundException("Glyph ID is out of bounds.");
+#endif
+    return 0;
+  }
+  return Loca(glyph_id + 1) - Loca(glyph_id);
+}
+
+int32_t LocaTable::NumLocas() {
+  return num_glyphs_ + 1;
+}
+
+int32_t LocaTable::Loca(int32_t index) {
+  if (index > num_glyphs_) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IndexOutOfBoundException();
+#endif
+    return 0;
+  }
+  if (format_version_ == IndexToLocFormat::kShortOffset) {
+    return 2 * data_->ReadUShort(index * DataSize::kUSHORT);
+  }
+  return data_->ReadULongAsInt(index * DataSize::kULONG);
+}
+
+LocaTable::LocaTable(Header* header,
+                     ReadableFontData* data,
+                     int32_t format_version,
+                     int32_t num_glyphs)
+    : Table(header, data),
+      format_version_(format_version),
+      num_glyphs_(num_glyphs) {
+}
+
+/******************************************************************************
+ * LocaTable::Iterator class
+ ******************************************************************************/
+LocaTable::LocaIterator::LocaIterator(LocaTable* table)
+    : PODIterator<int32_t, LocaTable>(table), index_(-1) {
+}
+
+bool LocaTable::LocaIterator::HasNext() {
+  return index_ <= container()->num_glyphs_;
+}
+
+int32_t LocaTable::LocaIterator::Next() {
+  return container()->Loca(index_++);
+}
+
+/******************************************************************************
+ * LocaTable::Builder class
+ ******************************************************************************/
+LocaTable::Builder::Builder(Header* header, WritableFontData* data)
+    : Table::Builder(header, data),
+      format_version_(IndexToLocFormat::kLongOffset),
+      num_glyphs_(-1) {
+}
+
+LocaTable::Builder::Builder(Header* header, ReadableFontData* data)
+    : Table::Builder(header, data),
+      format_version_(IndexToLocFormat::kLongOffset),
+      num_glyphs_(-1) {
+}
+
+LocaTable::Builder::~Builder() {}
+
+CALLER_ATTACH
+LocaTable::Builder* LocaTable::Builder::CreateBuilder(Header* header,
+                                                      WritableFontData* data) {
+  Ptr<LocaTable::Builder> builder;
+  builder = new LocaTable::Builder(header, data);
+  return builder.Detach();
+}
+
+IntegerList* LocaTable::Builder::LocaList() {
+  return GetLocaList();
+}
+
+void LocaTable::Builder::SetLocaList(IntegerList* list) {
+  loca_.clear();
+  if (list) {
+    loca_ = *list;
+    set_model_changed();
+  }
+}
+
+int32_t LocaTable::Builder::GlyphOffset(int32_t glyph_id) {
+  if (CheckGlyphRange(glyph_id) == -1) {
+    return 0;
+  }
+  return GetLocaList()->at(glyph_id);
+}
+
+int32_t LocaTable::Builder::GlyphLength(int32_t glyph_id) {
+  if (CheckGlyphRange(glyph_id) == -1) {
+    return 0;
+  }
+  return GetLocaList()->at(glyph_id + 1) - GetLocaList()->at(glyph_id);
+}
+
+void LocaTable::Builder::SetNumGlyphs(int32_t num_glyphs) {
+  num_glyphs_ = num_glyphs;
+}
+
+int32_t LocaTable::Builder::NumGlyphs() {
+  return LastGlyphIndex() - 1;
+}
+
+void LocaTable::Builder::Revert() {
+  loca_.clear();
+  set_model_changed(false);
+}
+
+int32_t LocaTable::Builder::NumLocas() {
+  return GetLocaList()->size();
+}
+
+int32_t LocaTable::Builder::Loca(int32_t index) {
+  return GetLocaList()->at(index);
+}
+
+CALLER_ATTACH
+FontDataTable* LocaTable::Builder::SubBuildTable(ReadableFontData* data) {
+  FontDataTablePtr table =
+      new LocaTable(header(), data, format_version_, num_glyphs_);
+  return table.Detach();
+}
+
+void LocaTable::Builder::SubDataSet() {
+  Initialize(InternalReadData());
+}
+
+int32_t LocaTable::Builder::SubDataSizeToSerialize() {
+  if (loca_.empty()) {
+    return 0;
+  }
+  if (format_version_ == IndexToLocFormat::kLongOffset) {
+    return loca_.size() * DataSize::kULONG;
+  }
+  return loca_.size() * DataSize::kUSHORT;
+}
+
+bool LocaTable::Builder::SubReadyToSerialize() {
+  return !loca_.empty();
+}
+
+int32_t LocaTable::Builder::SubSerialize(WritableFontData* new_data) {
+  int32_t size = 0;
+  for (IntegerList::iterator l = loca_.begin(), end = loca_.end();
+                             l != end; ++l) {
+    if (format_version_ == IndexToLocFormat::kLongOffset) {
+      size += new_data->WriteULong(size, *l);
+    } else {
+      size += new_data->WriteUShort(size, *l / 2);
+    }
+  }
+  num_glyphs_ = loca_.size() - 1;
+  return size;
+}
+
+void LocaTable::Builder::Initialize(ReadableFontData* data) {
+  ClearLoca(false);
+  if (data) {
+    if (NumGlyphs() < 0) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+      throw IllegalStateException("numglyphs not set on LocaTable Builder.");
+#endif
+      return;
+    }
+    LocaTablePtr table =
+        new LocaTable(header(), data, format_version_, num_glyphs_);
+    Ptr<LocaTable::LocaIterator> loca_iter =
+        new LocaTable::LocaIterator(table);
+    while (loca_iter->HasNext()) {
+      loca_.push_back(loca_iter->Next());
+    }
+  }
+}
+
+int32_t LocaTable::Builder::CheckGlyphRange(int32_t glyph_id) {
+  if (glyph_id < 0 || glyph_id > LastGlyphIndex()) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IndexOutOfBoundsException("Glyph ID is outside of the allowed range");
+#endif
+    return -1;
+  }
+  return glyph_id;
+}
+
+int32_t LocaTable::Builder::LastGlyphIndex() {
+  return !loca_.empty() ? loca_.size() - 2 : num_glyphs_ - 1;
+}
+
+IntegerList* LocaTable::Builder::GetLocaList() {
+  if (loca_.empty()) {
+    Initialize(InternalReadData());
+    set_model_changed();
+  }
+  return &loca_;
+}
+
+void LocaTable::Builder::ClearLoca(bool nullify) {
+  // Note: in C++ port, nullify is not used at all.
+  UNREFERENCED_PARAMETER(nullify);
+  loca_.clear();
+  set_model_changed(false);
+}
+
+}  // namespace sfntly
diff --git a/sfntly/table/truetype/loca_table.h b/sfntly/table/truetype/loca_table.h
new file mode 100644
index 0000000..67c5749
--- /dev/null
+++ b/sfntly/table/truetype/loca_table.h
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_TRUETYPE_LOCA_TABLE_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_TRUETYPE_LOCA_TABLE_H_
+
+#include "sfntly/port/java_iterator.h"
+#include "sfntly/table/table.h"
+#include "sfntly/table/core/font_header_table.h"
+
+namespace sfntly {
+
+// A Loca table - 'loca'.
+class LocaTable : public Table, public RefCounted<LocaTable> {
+ public:
+  class LocaIterator : public PODIterator<int32_t, LocaTable> {
+   public:
+    explicit LocaIterator(LocaTable* table);
+    virtual ~LocaIterator() {}
+
+    virtual bool HasNext();
+    virtual int32_t Next();
+
+   private:
+    int32_t index_;
+  };
+
+  class Builder : public Table::Builder, public RefCounted<Builder> {
+   public:
+    // Constructor scope altered to public for base class to instantiate.
+    Builder(Header* header, WritableFontData* data);
+    Builder(Header* header, ReadableFontData* data);
+    virtual ~Builder();
+
+    static CALLER_ATTACH Builder* CreateBuilder(Header* header,
+                                                WritableFontData* data);
+
+    // Get the format version that will be used when the loca table is
+    // generated.
+    // @return the loca table format version
+    int32_t format_version() { return format_version_; }
+    void set_format_version(int32_t value) { format_version_ = value; }
+
+    // Gets the List of locas for loca table builder. These may be manipulated
+    // in any way by the caller and the changes will be reflected in the final
+    // loca table produced as long as no subsequent call is made to the
+    // SetLocaList(List) method.
+    // If there is no current data for the loca table builder or the loca list
+    // have not been previously set then this will return an empty List.
+    IntegerList* LocaList();
+
+    // Set the list of locas to be used for building this table. If any existing
+    // list was already retrieved with the LocaList() method then the
+    // connection of that previous list to this builder will be broken.
+    void SetLocaList(IntegerList* list);
+
+    // Return the offset for the given glyph id. Valid glyph ids are from 0 to
+    // one less than the number of glyphs. The zero entry is the special entry
+    // for the notdef glyph. The final entry beyond the last glyph id is used to
+    // calculate the size of the last glyph.
+    // @param glyphId the glyph id to get the offset for; must be less than or
+    //        equal to one more than the number of glyph ids
+    // @return the offset in the glyph table to the specified glyph id
+    int32_t GlyphOffset(int32_t glyph_id);
+
+    // Get the length of the data in the glyph table for the specified glyph id.
+    int32_t GlyphLength(int32_t glyph_id);
+
+    // Set the number of glyphs.
+    // This method sets the number of glyphs that the builder will attempt to
+    // parse location data for from the raw binary data. This method only needs
+    // to be called (and <b>must</b> be) when the raw data for this builder has
+    // been changed. It does not by itself reset the data or clear any set loca
+    // list.
+    void SetNumGlyphs(int32_t num_glyphs);
+
+    // Get the number of glyphs that this builder has support for.
+    int NumGlyphs();
+
+    // Revert the loca table builder to the state contained in the last raw data
+    // set on the builder. That raw data may be that read from a font file when
+    // the font builder was created, that set by a user of the loca table
+    // builder, or null data if this builder was created as a new empty builder.
+    void Revert();
+
+    // Get the number of locations or locas. This will be one more than the
+    // number of glyphs for this table since the last loca position is used to
+    // indicate the size of the final glyph.
+    int32_t NumLocas();
+
+    // Get the value from the loca table for the index specified. These are the
+    // raw values from the table that are used to compute the offset and size of
+    // a glyph in the glyph table. Valid index values run from 0 to the number
+    // of glyphs in the font.
+    int32_t Loca(int32_t index);
+
+    virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+    virtual void SubDataSet();
+    virtual int32_t SubDataSizeToSerialize();
+    virtual bool SubReadyToSerialize();
+    virtual int32_t SubSerialize(WritableFontData* new_data);
+
+   private:
+    // Initialize the internal state from the data. Done lazily since in many
+    // cases the builder will be just creating a table object with no parsing
+    // required.
+    // @param data the data to initialize from
+    void Initialize(ReadableFontData* data);
+
+    // Checks that the glyph id is within the correct range.
+    // @return glyph_id if correct, -1 otherwise.
+    int32_t CheckGlyphRange(int32_t glyph_id);
+
+    int32_t LastGlyphIndex();
+
+    // Internal method to get the loca list if already generated and if not to
+    // initialize the state of the builder.
+    // @return the loca list
+    IntegerList* GetLocaList();
+
+    void ClearLoca(bool nullify);
+
+    int32_t format_version_;  // Note: IndexToLocFormat
+    int32_t num_glyphs_;
+    IntegerList loca_;
+  };
+
+  virtual ~LocaTable();
+
+  int32_t format_version() { return format_version_; }
+  int32_t num_glyphs() { return num_glyphs_; }
+
+  // Return the offset for the given glyph id. Valid glyph ids are from 0 to the
+  // one less than the number of glyphs. The zero entry is the special entry for
+  // the notdef glyph. The final entry beyond the last glyph id is used to
+  // calculate the size of the last glyph.
+  // @param glyphId the glyph id to get the offset for; must be less than or
+  //        equal to one more than the number of glyph ids
+  // @return the offset in the glyph table to the specified glyph id
+  int32_t GlyphOffset(int32_t glyph_id);
+
+  // Get the length of the data in the glyph table for the specified glyph id.
+  int32_t GlyphLength(int32_t glyph_id);
+
+  // Get the number of locations or locas. This will be one more than the number
+  // of glyphs for this table since the last loca position is used to indicate
+  // the size of the final glyph.
+  int32_t NumLocas();
+
+  // Get the value from the loca table for the index specified. Valid index
+  // values run from 0 to the number of glyphs in the font.
+  int32_t Loca(int32_t index);
+
+ private:
+  LocaTable(Header* header,
+            ReadableFontData* data,
+            int32_t format_version,
+            int32_t num_glyphs);
+
+  int32_t format_version_;  // Note: Java's version, renamed to format_version_
+  int32_t num_glyphs_;
+
+  friend class LocaIterator;
+};
+typedef Ptr<LocaTable> LocaTablePtr;
+typedef Ptr<LocaTable::Builder> LocaTableBuilderPtr;
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_TRUETYPE_LOCA_TABLE_H_
diff --git a/sfntly/tag.cc b/sfntly/tag.cc
new file mode 100644
index 0000000..c9d8c29
--- /dev/null
+++ b/sfntly/tag.cc
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/tag.h"
+#include "sfntly/port/endian.h"
+
+// Use a macro instead of GenerateTag() because gcc 4.4.3 creates static
+// initializers in that case.
+#define TAG(a, b, c, d) ((a << 24) | (b << 16) | (c << 8) | d);
+
+namespace sfntly {
+
+const int32_t Tag::ttcf = TAG('t', 't', 'c', 'f');
+const int32_t Tag::cmap = TAG('c', 'm', 'a', 'p');
+const int32_t Tag::head = TAG('h', 'e', 'a', 'd');
+const int32_t Tag::hhea = TAG('h', 'h', 'e', 'a');
+const int32_t Tag::hmtx = TAG('h', 'm', 't', 'x');
+const int32_t Tag::maxp = TAG('m', 'a', 'x', 'p');
+const int32_t Tag::name = TAG('n', 'a', 'm', 'e');
+const int32_t Tag::OS_2 = TAG('O', 'S', '/', '2');
+const int32_t Tag::post = TAG('p', 'o', 's', 't');
+const int32_t Tag::cvt  = TAG('c', 'v', 't', ' ');
+const int32_t Tag::fpgm = TAG('f', 'p', 'g', 'm');
+const int32_t Tag::glyf = TAG('g', 'l', 'y', 'f');
+const int32_t Tag::loca = TAG('l', 'o', 'c', 'a');
+const int32_t Tag::prep = TAG('p', 'r', 'e', 'p');
+const int32_t Tag::CFF  = TAG('C', 'F', 'F', ' ');
+const int32_t Tag::VORG = TAG('V', 'O', 'R', 'G');
+const int32_t Tag::EBDT = TAG('E', 'B', 'D', 'T');
+const int32_t Tag::EBLC = TAG('E', 'B', 'L', 'C');
+const int32_t Tag::EBSC = TAG('E', 'B', 'S', 'C');
+const int32_t Tag::BASE = TAG('B', 'A', 'S', 'E');
+const int32_t Tag::GDEF = TAG('G', 'D', 'E', 'F');
+const int32_t Tag::GPOS = TAG('G', 'P', 'O', 'S');
+const int32_t Tag::GSUB = TAG('G', 'S', 'U', 'B');
+const int32_t Tag::JSTF = TAG('J', 'S', 'T', 'F');
+const int32_t Tag::DSIG = TAG('D', 'S', 'I', 'G');
+const int32_t Tag::gasp = TAG('g', 'a', 's', 'p');
+const int32_t Tag::hdmx = TAG('h', 'd', 'm', 'x');
+const int32_t Tag::kern = TAG('k', 'e', 'r', 'n');
+const int32_t Tag::LTSH = TAG('L', 'T', 'S', 'H');
+const int32_t Tag::PCLT = TAG('P', 'C', 'L', 'T');
+const int32_t Tag::VDMX = TAG('V', 'D', 'M', 'X');
+const int32_t Tag::vhea = TAG('v', 'h', 'e', 'a');
+const int32_t Tag::vmtx = TAG('v', 'm', 't', 'x');
+const int32_t Tag::bsln = TAG('b', 's', 'l', 'n');
+const int32_t Tag::feat = TAG('f', 'e', 'a', 't');
+const int32_t Tag::lcar = TAG('l', 'c', 'a', 'r');
+const int32_t Tag::morx = TAG('m', 'o', 'r', 'x');
+const int32_t Tag::opbd = TAG('o', 'p', 'b', 'd');
+const int32_t Tag::prop = TAG('p', 'r', 'o', 'p');
+const int32_t Tag::Feat = TAG('F', 'e', 'a', 't');
+const int32_t Tag::Glat = TAG('G', 'l', 'a', 't');
+const int32_t Tag::Gloc = TAG('G', 'l', 'o', 'c');
+const int32_t Tag::Sile = TAG('S', 'i', 'l', 'e');
+const int32_t Tag::Silf = TAG('S', 'i', 'l', 'f');
+const int32_t Tag::bhed = TAG('b', 'h', 'e', 'd');
+const int32_t Tag::bdat = TAG('b', 'd', 'a', 't');
+const int32_t Tag::bloc = TAG('b', 'l', 'o', 'c');
+
+const int32_t CFF_TABLE_ORDERING[] = {
+    Tag::head,
+    Tag::hhea,
+    Tag::maxp,
+    Tag::OS_2,
+    Tag::name,
+    Tag::cmap,
+    Tag::post,
+    Tag::CFF };
+const size_t CFF_TABLE_ORDERING_SIZE =
+    sizeof(CFF_TABLE_ORDERING) / sizeof(int32_t);
+
+const int32_t TRUE_TYPE_TABLE_ORDERING[] = {
+    Tag::head,
+    Tag::hhea,
+    Tag::maxp,
+    Tag::OS_2,
+    Tag::hmtx,
+    Tag::LTSH,
+    Tag::VDMX,
+    Tag::hdmx,
+    Tag::cmap,
+    Tag::fpgm,
+    Tag::prep,
+    Tag::cvt,
+    Tag::loca,
+    Tag::glyf,
+    Tag::kern,
+    Tag::name,
+    Tag::post,
+    Tag::gasp,
+    Tag::PCLT,
+    Tag::DSIG };
+const size_t TRUE_TYPE_TABLE_ORDERING_SIZE =
+    sizeof(TRUE_TYPE_TABLE_ORDERING) / sizeof(int32_t);
+
+}  // namespace sfntly
diff --git a/sfntly/tag.h b/sfntly/tag.h
new file mode 100644
index 0000000..0ecbab8
--- /dev/null
+++ b/sfntly/tag.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TAG_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TAG_H_
+
+#include <cstddef>
+
+#include "sfntly/port/type.h"
+
+namespace sfntly {
+
+// Font identification tags used for tables, features, etc.
+// Tag names are consistent with the OpenType and sfnt specs.
+struct Tag {
+  static const int32_t ttcf;
+
+  // Table Type Tags
+  // required tables
+  static const int32_t cmap;
+  static const int32_t head;
+  static const int32_t hhea;
+  static const int32_t hmtx;
+  static const int32_t maxp;
+  static const int32_t name;
+  static const int32_t OS_2;
+  static const int32_t post;
+
+  // TrueType outline tables
+  static const int32_t cvt;
+  static const int32_t fpgm;
+  static const int32_t glyf;
+  static const int32_t loca;
+  static const int32_t prep;
+
+  // PostScript outline tables
+  static const int32_t CFF;
+  static const int32_t VORG;
+
+  // opentype bitmap glyph outlines
+  static const int32_t EBDT;
+  static const int32_t EBLC;
+  static const int32_t EBSC;
+
+  // advanced typographic features
+  static const int32_t BASE;
+  static const int32_t GDEF;
+  static const int32_t GPOS;
+  static const int32_t GSUB;
+  static const int32_t JSTF;
+
+  // other
+  static const int32_t DSIG;
+  static const int32_t gasp;
+  static const int32_t hdmx;
+  static const int32_t kern;
+  static const int32_t LTSH;
+  static const int32_t PCLT;
+  static const int32_t VDMX;
+  static const int32_t vhea;
+  static const int32_t vmtx;
+
+  // AAT tables
+  static const int32_t bsln;
+  static const int32_t feat;
+  static const int32_t lcar;
+  static const int32_t morx;
+  static const int32_t opbd;
+  static const int32_t prop;
+
+  // Graphite tables
+  static const int32_t Feat;
+  static const int32_t Glat;
+  static const int32_t Gloc;
+  static const int32_t Sile;
+  static const int32_t Silf;
+
+  // truetype bitmap font tables
+  static const int32_t bhed;
+  static const int32_t bdat;
+  static const int32_t bloc;
+};
+
+// Create integer tag value for human readable tag name.
+inline int32_t GenerateTag(int32_t a, int32_t b, int32_t c, int32_t d) {
+  return (a << 24) | (b << 16) | (c << 8) | d;
+}
+
+// Translate tag to human readable string.
+// The Caller must delete[] the returned value.
+inline char* TagToString(int32_t tag) {
+  char *name = new char[5];
+  name[0] = static_cast<char>((tag & 0xff000000) >> 24);
+  name[1] = static_cast<char>((tag & 0x00ff0000) >> 16);
+  name[2] = static_cast<char>((tag & 0x0000ff00) >> 8);
+  name[3] = static_cast<char>(tag & 0x000000ff);
+  name[4] = 0;
+  return name;
+}
+
+// Note: For Java, these two orderings are in Font class.  Moved here to avoid
+//       VC++ bug of not populating correct values.
+extern const int32_t CFF_TABLE_ORDERING[];
+extern const size_t CFF_TABLE_ORDERING_SIZE;
+extern const int32_t TRUE_TYPE_TABLE_ORDERING[];
+extern const size_t TRUE_TYPE_TABLE_ORDERING_SIZE;
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_TAG_H_
diff --git a/sfntly/tools/subsetter/glyph_table_subsetter.cc b/sfntly/tools/subsetter/glyph_table_subsetter.cc
new file mode 100644
index 0000000..b3d6b07
--- /dev/null
+++ b/sfntly/tools/subsetter/glyph_table_subsetter.cc
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/tools/subsetter/glyph_table_subsetter.h"
+
+#include "sfntly/table/truetype/glyph_table.h"
+#include "sfntly/table/truetype/loca_table.h"
+#include "sfntly/tag.h"
+#include "sfntly/tools/subsetter/subsetter.h"
+#include "sfntly/port/exception_type.h"
+
+namespace sfntly {
+
+const int32_t kGlyphTableSubsetterTags[2] = {Tag::glyf, Tag::loca};
+
+GlyphTableSubsetter::GlyphTableSubsetter()
+    : TableSubsetterImpl(kGlyphTableSubsetterTags, 2) {
+}
+
+GlyphTableSubsetter::~GlyphTableSubsetter() {}
+
+bool GlyphTableSubsetter::Subset(Subsetter* subsetter,
+                                 Font* font,
+                                 Font::Builder* font_builder) {
+  assert(font);
+  assert(subsetter);
+  assert(font_builder);
+
+  IntegerList* permutation_table = subsetter->GlyphPermutationTable();
+  if (!permutation_table || permutation_table->empty())
+    return false;
+
+  GlyphTablePtr glyph_table = down_cast<GlyphTable*>(font->GetTable(Tag::glyf));
+  LocaTablePtr loca_table = down_cast<LocaTable*>(font->GetTable(Tag::loca));
+  if (glyph_table == NULL || loca_table == NULL) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw RuntimeException("Font to subset is not valid.");
+#endif
+    return false;
+  }
+
+  GlyphTableBuilderPtr glyph_table_builder =
+      down_cast<GlyphTable::Builder*>
+      (font_builder->NewTableBuilder(Tag::glyf));
+  LocaTableBuilderPtr loca_table_builder =
+      down_cast<LocaTable::Builder*>
+      (font_builder->NewTableBuilder(Tag::loca));
+  if (glyph_table_builder == NULL || loca_table_builder == NULL) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw RuntimeException("Builder for subset is not valid.");
+#endif
+    return false;
+  }
+  GlyphTable::GlyphBuilderList* glyph_builders =
+      glyph_table_builder->GlyphBuilders();
+  for (IntegerList::iterator old_glyph_id = permutation_table->begin(),
+                             old_glyph_id_end = permutation_table->end();
+                             old_glyph_id != old_glyph_id_end; ++old_glyph_id) {
+    int old_offset = loca_table->GlyphOffset(*old_glyph_id);
+    int old_length = loca_table->GlyphLength(*old_glyph_id);
+    GlyphPtr glyph;
+    glyph.Attach(glyph_table->GetGlyph(old_offset, old_length));
+    ReadableFontDataPtr data = glyph->ReadFontData();
+    WritableFontDataPtr copy_data;
+    copy_data.Attach(WritableFontData::CreateWritableFontData(data->Length()));
+    data->CopyTo(copy_data);
+    GlyphBuilderPtr glyph_builder;
+    glyph_builder.Attach(glyph_table_builder->GlyphBuilder(copy_data));
+    glyph_builders->push_back(glyph_builder);
+  }
+  IntegerList loca_list;
+  glyph_table_builder->GenerateLocaList(&loca_list);
+  loca_table_builder->SetLocaList(&loca_list);
+  return true;
+}
+
+}  // namespace sfntly
diff --git a/sfntly/tools/subsetter/glyph_table_subsetter.h b/sfntly/tools/subsetter/glyph_table_subsetter.h
new file mode 100644
index 0000000..88c7044
--- /dev/null
+++ b/sfntly/tools/subsetter/glyph_table_subsetter.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TOOLS_SUBSETTER_GLYPH_TABLE_SUBSETTER_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TOOLS_SUBSETTER_GLYPH_TABLE_SUBSETTER_H_
+
+#include "sfntly/tools/subsetter/table_subsetter_impl.h"
+
+namespace sfntly {
+
+class GlyphTableSubsetter : public TableSubsetterImpl,
+                            public RefCounted<GlyphTableSubsetter> {
+ public:
+  GlyphTableSubsetter();
+  virtual ~GlyphTableSubsetter();
+
+  virtual bool Subset(Subsetter* subsetter,
+                      Font* font,
+                      Font::Builder* font_builder);
+};
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_TOOLS_SUBSETTER_GLYPH_TABLE_SUBSETTER_H_
diff --git a/sfntly/tools/subsetter/subsetter.cc b/sfntly/tools/subsetter/subsetter.cc
new file mode 100644
index 0000000..7d98779
--- /dev/null
+++ b/sfntly/tools/subsetter/subsetter.cc
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/tools/subsetter/subsetter.h"
+
+#include <algorithm>
+#include <iterator>
+
+#include "sfntly/tools/subsetter/glyph_table_subsetter.h"
+
+namespace sfntly {
+
+Subsetter::Subsetter(Font* font, FontFactory* font_factory) {
+  font_ = font;
+  font_factory_ = font_factory;
+  TableSubsetterPtr subsetter = new GlyphTableSubsetter();
+  // TODO(arthurhsu): IMPLEMENT: CMap table subsetter
+  table_subsetters_.push_back(subsetter);
+}
+
+Subsetter::~Subsetter() {
+  font_factory_.Release();
+  font_.Release();
+  table_subsetters_.clear();
+}
+
+void Subsetter::SetGlyphs(IntegerList* glyphs) {
+  new_to_old_glyphs_ = *glyphs;
+}
+
+void Subsetter::SetCMaps(CMapIdList* cmap_ids, int32_t number) {
+  UNREFERENCED_PARAMETER(cmap_ids);
+  UNREFERENCED_PARAMETER(number);
+  // TODO(arthurhsu): IMPLEMENT
+}
+
+void Subsetter::SetRemoveTables(IntegerSet* remove_tables) {
+  remove_tables_ = *remove_tables;
+}
+
+CALLER_ATTACH Font::Builder* Subsetter::Subset() {
+  FontBuilderPtr font_builder;
+  font_builder.Attach(font_factory_->NewFontBuilder());
+
+  IntegerSet table_tags;
+  for (TableMap::const_iterator i = font_->GetTableMap()->begin(),
+                                e = font_->GetTableMap()->end(); i != e; ++i) {
+    table_tags.insert(i->first);
+  }
+  if (!remove_tables_.empty()) {
+    IntegerSet result;
+    std::set_difference(table_tags.begin(), table_tags.end(),
+                        remove_tables_.begin(), remove_tables_.end(),
+                        std::inserter(result, result.end()));
+    table_tags = result;
+  }
+  for (TableSubsetterList::iterator
+           table_subsetter = table_subsetters_.begin(),
+           table_subsetter_end = table_subsetters_.end();
+           table_subsetter != table_subsetter_end; ++table_subsetter) {
+    bool handled = (*table_subsetter)->Subset(this, font_, font_builder);
+    if (handled) {
+      IntegerSet* handled_tags = (*table_subsetter)->TagsHandled();
+      IntegerSet result;
+      std::set_difference(table_tags.begin(), table_tags.end(),
+                          handled_tags->begin(), handled_tags->end(),
+                          std::inserter(result, result.end()));
+      table_tags = result;
+    }
+  }
+  for (IntegerSet::iterator tag = table_tags.begin(),
+                            tag_end = table_tags.end(); tag != tag_end; ++tag) {
+    Table* table = font_->GetTable(*tag);
+    if (table) {
+      font_builder->NewTableBuilder(*tag, table->ReadFontData());
+    }
+  }
+  return font_builder.Detach();
+}
+
+IntegerList* Subsetter::GlyphPermutationTable() {
+  return &new_to_old_glyphs_;
+}
+
+CMapIdList* Subsetter::CMapId() {
+  return &cmap_ids_;
+}
+
+}  // namespace sfntly
diff --git a/sfntly/tools/subsetter/subsetter.h b/sfntly/tools/subsetter/subsetter.h
new file mode 100644
index 0000000..85940a7
--- /dev/null
+++ b/sfntly/tools/subsetter/subsetter.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TOOLS_SUBSETTER_SUBSETTER_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TOOLS_SUBSETTER_SUBSETTER_H_
+
+#include <vector>
+
+#include "sfntly/font.h"
+#include "sfntly/font_factory.h"
+#include "sfntly/table/core/cmap_table.h"
+#include "sfntly/tools/subsetter/table_subsetter.h"
+
+namespace sfntly {
+
+class Subsetter : public RefCounted<Subsetter> {
+ public:
+  Subsetter(Font* font, FontFactory* font_factory);
+  virtual ~Subsetter();
+
+  virtual void SetGlyphs(IntegerList* glyphs);
+
+  // Set the cmaps to be used in the subsetted font. The cmaps are listed in
+  // order of priority and the number parameter gives a count of how many of the
+  // list should be put into the subsetted font. If there are no matches in the
+  // font for any of the provided cmap ids which would lead to a font with no
+  // cmap then an error will be thrown during subsetting.
+  // The two most common cases would be: <list>
+  // * a list of one or more cmap ids with a count setting of 1
+  //     This will use the list of cmap ids as an ordered priority and look for
+  //     an available cmap in the font that matches the requests. Only the first
+  //     such match will be placed in the subsetted font.
+  // * a list of one or more cmap ids with a count setting equal to the list
+  //   length
+  //     This will use the list of cmap ids and try to place each one specified
+  //     into the subsetted font.
+  // @param cmapIds the cmap ids to use for the subsetted font
+  // @param number the maximum number of cmaps to place in the subsetted font
+  virtual void SetCMaps(CMapIdList* cmap_ids, int32_t number);
+
+  virtual void SetRemoveTables(IntegerSet* remove_tables);
+  virtual CALLER_ATTACH Font::Builder* Subset();
+  virtual IntegerList* GlyphPermutationTable();
+  virtual CMapIdList* CMapId();
+
+ private:
+  FontPtr font_;
+  FontFactoryPtr font_factory_;
+  TableSubsetterList table_subsetters_;
+
+  // Settings from user
+  IntegerSet remove_tables_;
+  IntegerList new_to_old_glyphs_;
+  CMapIdList cmap_ids_;
+};
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_TOOLS_SUBSETTER_SUBSETTER_H_
diff --git a/sfntly/tools/subsetter/table_subsetter.h b/sfntly/tools/subsetter/table_subsetter.h
new file mode 100644
index 0000000..1336615
--- /dev/null
+++ b/sfntly/tools/subsetter/table_subsetter.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TOOLS_SUBSETTER_TABLE_SUBSETTER_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TOOLS_SUBSETTER_TABLE_SUBSETTER_H_
+
+#include <vector>
+
+#include "sfntly/font.h"
+
+namespace sfntly {
+
+class Subsetter;
+class TableSubsetter : virtual public RefCount {
+ public:
+  virtual IntegerSet* TagsHandled() = 0;
+  virtual bool TagHandled(int32_t tag) = 0;
+  virtual bool Subset(Subsetter* subsetter, Font* font,
+                      Font::Builder* font_builder) = 0;
+};
+typedef Ptr<TableSubsetter> TableSubsetterPtr;
+typedef std::vector<TableSubsetterPtr> TableSubsetterList;
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_TOOLS_SUBSETTER_TABLE_SUBSETTER_H_
diff --git a/sfntly/tools/subsetter/table_subsetter_impl.cc b/sfntly/tools/subsetter/table_subsetter_impl.cc
new file mode 100644
index 0000000..f239c78
--- /dev/null
+++ b/sfntly/tools/subsetter/table_subsetter_impl.cc
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/tools/subsetter/table_subsetter_impl.h"
+
+namespace sfntly {
+
+TableSubsetterImpl::TableSubsetterImpl(const int32_t* tags,
+                                       size_t tags_length) {
+  for (size_t i = 0; i < tags_length; ++i) {
+    tags_.insert(tags[i]);
+  }
+}
+
+TableSubsetterImpl::~TableSubsetterImpl() {}
+
+bool TableSubsetterImpl::TagHandled(int32_t tag) {
+  return tags_.find(tag) != tags_.end();
+}
+
+IntegerSet* TableSubsetterImpl::TagsHandled() {
+  return &tags_;
+}
+
+}  // namespace sfntly
diff --git a/sfntly/tools/subsetter/table_subsetter_impl.h b/sfntly/tools/subsetter/table_subsetter_impl.h
new file mode 100644
index 0000000..de0d9a9
--- /dev/null
+++ b/sfntly/tools/subsetter/table_subsetter_impl.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TOOLS_SUBSETTER_TABLE_SUBSETTER_IMPL_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TOOLS_SUBSETTER_TABLE_SUBSETTER_IMPL_H_
+
+#include "sfntly/tools/subsetter/table_subsetter.h"
+
+namespace sfntly {
+
+class TableSubsetterImpl : public TableSubsetter {
+ public:
+  TableSubsetterImpl(const int32_t* tags, size_t tags_length);
+  virtual ~TableSubsetterImpl();
+  virtual bool TagHandled(int32_t tag);
+  virtual IntegerSet* TagsHandled();
+
+ protected:
+  IntegerSet tags_;
+};
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_SFNTLY_TOOLS_SUBSETTER_TABLE_SUBSETTER_IMPL_H_
diff --git a/test/autogenerated/cmap_basic_test.cc b/test/autogenerated/cmap_basic_test.cc
new file mode 100644
index 0000000..aae35e1
--- /dev/null
+++ b/test/autogenerated/cmap_basic_test.cc
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+// type.h needs to be included first because of building issues on Windows
+// Type aliases we delcare are defined in other headers and make the build
+// fail otherwise.
+#include "sfntly/port/type.h"
+#include <assert.h>
+#include <stdio.h>
+#include <unicode/ucnv.h>
+
+#include <iostream>
+#include <string>
+
+#include "gtest/gtest.h"
+#include "sfntly/data/memory_byte_array.h"
+#include "sfntly/font.h"
+#include "sfntly/font_factory.h"
+#include "sfntly/table/core/cmap_table.h"
+#include "sfntly/table/core/font_header_table.h"
+#include "sfntly/tag.h"
+#include "test/autogenerated/cmap_test_data.h"
+#include "test/test_font_utils.h"
+#include "test/test_utils.h"
+#include "test/test_xml_utils.h"
+
+namespace sfntly {
+
+#if GTEST_HAS_PARAM_TEST
+
+using ::testing::TestWithParam;
+using ::testing::Values;
+
+class CMapBasicTests : public :: testing::TestWithParam<const char*> {
+ public:
+  CMapBasicTests() {}
+  virtual void SetUp();
+  virtual void TearDown() {}
+
+  Ptr<CMapTable> cmap_table_;
+  TiXmlDocument document_;
+};
+
+void CMapBasicTests::SetUp() {
+  // Loading the font
+  Ptr<FontFactory> font_factory;
+  font_factory.Attach(FontFactory::GetInstance());
+  FontArray font_array;
+  std::string font_name = "../../";
+#if defined (WIN32)
+  font_name += "../";
+#endif
+  font_name += std::string(GetParam());
+  LoadFont(font_name.c_str(), font_factory, &font_array);
+  ASSERT_FALSE(font_array.empty());
+  Ptr<Font> font = font_array.at(0);
+  ASSERT_NE(font, reinterpret_cast<Font*>(NULL));
+  cmap_table_ = down_cast<CMapTable*>(font->GetTable(Tag::cmap));
+  if (!cmap_table_)
+    fprintf(stderr, "No CMap: %s\n", font_name.c_str());
+  ASSERT_NE(cmap_table_, reinterpret_cast<CMapTable*>(NULL));
+
+  // Loading the XML file
+  document_ = TiXmlDocument((font_name + ".xml").c_str());
+  ASSERT_TRUE(document_.LoadFile());
+}
+
+TEST_P(CMapBasicTests, BasicTest) {
+  TiXmlNodeVector* cmap_table = GetNodesWithName(&document_, "cmap_table");
+  // A font can only have one CMap table
+  ASSERT_EQ(cmap_table->size(), (size_t)1);
+  TiXmlNodeVector* cmaps = GetNodesWithName(cmap_table->at(0), "cmap");
+  const TiXmlAttribute* num_cmaps_attr = GetAttribute(cmap_table->at(0),
+                                                      "num_cmaps");
+  ASSERT_NE(num_cmaps_attr, reinterpret_cast<TiXmlAttribute*>(NULL));
+  // But there may be more than one CMap in this table
+  ASSERT_LE(cmaps->size(), (size_t)num_cmaps_attr->IntValue());
+  for (TiXmlNodeVector::iterator it = cmaps->begin();
+       it != cmaps->end(); ++it) {
+    int32_t platform_id = GetAttribute(*it, "platform_id")->IntValue();
+    int32_t encoding_id = GetAttribute(*it, "encoding_id")->IntValue();
+    Ptr<CMapTable::CMap> cmap;
+    cmap.Attach(cmap_table_->GetCMap(platform_id, encoding_id));
+    if (!cmap) {
+      fprintf(stderr, "Cannot test unsupported CMapFormat%d\n",
+              GetAttribute(*it, "format")->IntValue());
+      continue;
+    }
+    ASSERT_EQ(cmap->platform_id(), platform_id);
+    ASSERT_EQ(cmap->encoding_id(), encoding_id);
+    TiXmlNodeVector* maps = GetNodesWithName(*it, "map");
+    for (TiXmlNodeVector::iterator jt = maps->begin();
+         jt != maps->end(); ++jt) {
+      int32_t character;
+#if defined (WIN32)
+      sscanf_s(GetAttribute(*jt, "char")->Value(), "%x", &character);
+#else
+      sscanf(GetAttribute(*jt, "char")->Value(), "%x", &character);
+#endif
+      int32_t glyph_id = GetAttribute(*jt, "gid")->IntValue();
+      ASSERT_EQ(cmap->GlyphId(character), glyph_id);
+    }
+    delete maps;
+  }
+  delete cmaps;
+  delete cmap_table;
+}
+
+INSTANTIATE_TEST_CASE_P(CMapBasicTests,
+                        CMapBasicTests,
+                        ::testing::ValuesIn(cmap_test_data::kAllTests));
+
+#else
+
+TEST(DummyTest, ValueParameterizedTestsAreNotSupportedOnThisPlatform) {}
+
+#endif  // GTEST_HAS_PARAM
+}
diff --git a/test/autogenerated/cmap_test_data.h b/test/autogenerated/cmap_test_data.h
new file mode 100644
index 0000000..4a9f267
--- /dev/null
+++ b/test/autogenerated/cmap_test_data.h
@@ -0,0 +1,185 @@
+/*
+ * !!! DO NOT EDIT !!!
+ * THIS FILE IS GENERATED BY A SCRIPT.
+ * FOR MORE DETAILS SEE 'README-test_data.txt'.
+ */
+
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef TYPOGRAPHY_FONT_SFNTLY_SRC_TEST_AUTOGENERATED_CMAP_TEST_DATA_H_
+#define TYPOGRAPHY_FONT_SFNTLY_SRC_TEST_AUTOGENERATED_CMAP_TEST_DATA_H_
+
+#include "sfntly/port/type.h"
+
+namespace sfntly {
+namespace cmap_test_data {
+const char* kAllTests[] = {
+  "data/fonts/cousine/Cousine-BoldItalic.ttf",
+  "data/fonts/cousine/Cousine-Bold.ttf",
+  "data/fonts/cousine/Cousine-Regular.ttf",
+  "data/fonts/cousine/Cousine-Italic.ttf",
+  "data/fonts/cedarvillecursive/Cedarville-Cursive.ttf",
+  "data/fonts/dancingscript/DancingScript-Bold.ttf",
+  "data/fonts/dancingscript/DancingScript-Regular.ttf",
+  "data/fonts/damion/Damion-Regular.ttf",
+  "data/fonts/annieuseyourtelescope/AnnieUseYourTelescope.ttf",
+  "data/fonts/deliusswashcaps/DeliusSwashCaps-Regular.ttf",
+  "data/fonts/delius/Delius-Regular.ttf",
+  "data/fonts/coveredbyyourgrace/CoveredByYourGrace.ttf",
+  "data/fonts/ebgaramond/EBGaramond-Regular.ttf",
+  "data/fonts/cabinsketch/CabinSketch-Bold.ttf",
+  "data/fonts/allan/Allan-Bold.ttf",
+  "data/fonts/coda/Coda-Caption-Heavy.ttf",
+  "data/fonts/coda/Coda-Heavy.ttf",
+  "data/fonts/forum/Forum-Regular.ttf",
+  "data/fonts/alike/Alike-Regular.ttf",
+  "data/fonts/corben/Corben-Bold.ttf",
+  "data/fonts/caudex/Caudex-Regular.ttf",
+  "data/fonts/caudex/Caudex-BoldItalic.ttf",
+  "data/fonts/caudex/Caudex-Italic.ttf",
+  "data/fonts/caudex/Caudex-Bold.ttf",
+  "data/fonts/cabin/Cabin-MediumItalic.ttf",
+  "data/fonts/cabin/Cabin-SemiBold.ttf",
+  "data/fonts/cabin/Cabin-SemiBoldItalic.ttf",
+  "data/fonts/cabin/Cabin-BoldItalic.ttf",
+  "data/fonts/cabin/Cabin-Medium.ttf",
+  "data/fonts/cabin/Cabin-Italic.ttf",
+  "data/fonts/cabin/Cabin-Bold.ttf",
+  "data/fonts/cabin/Cabin-Regular.ttf",
+  "data/fonts/dawningofanewday/DawningofaNewDay.ttf",
+  "data/fonts/dangrek/Dangrek.ttf",
+  "data/fonts/blackopsone/BlackOpsOne.ttf",
+  "data/fonts/francoisone/FrancoisOne.ttf",
+  "data/fonts/bowlbyone/BowlbyOne.ttf",
+  "data/fonts/bowlbyone/BowlbyOneSC.ttf",
+  "data/fonts/calligraffiti/Calligraffiti.ttf",
+  "data/fonts/bangers/Bangers.ttf",
+  "data/fonts/astloch/Astloch-Regular.ttf",
+  "data/fonts/astloch/Astloch-Bold.ttf",
+  "data/fonts/angkor/Angkor.ttf",
+  "data/fonts/abrilfatface/AbrilFatface-Regular.ttf",
+  "data/fonts/cantarell/Cantarell-BoldOblique.ttf",
+  "data/fonts/cantarell/Cantarell-Oblique.ttf",
+  "data/fonts/cantarell/Cantarell-Bold.ttf",
+  "data/fonts/cantarell/Cantarell-Regular.ttf",
+  "data/fonts/arvo/Arvo-Bold.ttf",
+  "data/fonts/arvo/Arvo-Italic.ttf",
+  "data/fonts/arvo/Arvo-BoldItalic.ttf",
+  "data/fonts/arvo/Arvo-Regular.ttf",
+  "data/fonts/chewy/Chewy.ttf",
+  "data/fonts/bigshotone/BigshotOne.ttf",
+  "data/fonts/chenla/Chenla.ttf",
+  "data/fonts/bayon/Bayon.ttf",
+  "data/fonts/coustard/Coustard-Black.ttf",
+  "data/fonts/coustard/Coustard-Regular.ttf",
+  "data/fonts/amaticsc/AmaticSC-Bold.ttf",
+  "data/fonts/amaticsc/AmaticSC-Regular.ttf",
+  "data/fonts/comfortaa/Comfortaa-Light.ttf",
+  "data/fonts/comfortaa/Comfortaa-Bold.ttf",
+  "data/fonts/comfortaa/Comfortaa-Regular.ttf",
+  "data/fonts/expletussans/ExpletusSans-Bold.ttf",
+  "data/fonts/expletussans/ExpletusSans-MediumItalic.ttf",
+  "data/fonts/expletussans/ExpletusSans-Medium.ttf",
+  "data/fonts/expletussans/ExpletusSans-SemiBold.ttf",
+  "data/fonts/expletussans/ExpletusSans-Regular.ttf",
+  "data/fonts/expletussans/ExpletusSans-Italic.ttf",
+  "data/fonts/expletussans/ExpletusSans-SemiBoldItalic.ttf",
+  "data/fonts/expletussans/ExpletusSans-BoldItalic.ttf",
+  "data/fonts/aubrey/Aubrey-Regular.ttf",
+  "data/fonts/antic/Antic-Regular.ttf",
+  "data/fonts/copse/Copse-Regular.ttf",
+  "data/fonts/daysone/DaysOne-Regular.ttf",
+  "data/fonts/actor/Actor-Regular.ttf",
+  "data/fonts/bentham/Bentham-Regular.ttf",
+  "data/fonts/federo/Federo-Regular.ttf",
+  "data/fonts/arimo/Arimo-Italic.ttf",
+  "data/fonts/arimo/Arimo-BoldItalic.ttf",
+  "data/fonts/arimo/Arimo-Bold.ttf",
+  "data/fonts/arimo/Arimo-Regular.ttf",
+  "data/fonts/felltypes/IMFeDPsc28P.ttf",
+  "data/fonts/felltypes/IMFeGPrm28P.ttf",
+  "data/fonts/felltypes/IMFeENsc28P.ttf",
+  "data/fonts/felltypes/IMFePIit28P.ttf",
+  "data/fonts/felltypes/IMFeDPrm28P.ttf",
+  "data/fonts/felltypes/IMFePIrm28P.ttf",
+  "data/fonts/felltypes/IMFeFCrm28P.ttf",
+  "data/fonts/felltypes/IMFeGPit28P.ttf",
+  "data/fonts/felltypes/IMFeENit28P.ttf",
+  "data/fonts/felltypes/IMFeDPit28P.ttf",
+  "data/fonts/felltypes/IMFeENrm28P.ttf",
+  "data/fonts/felltypes/IMFeGPsc28P.ttf",
+  "data/fonts/felltypes/IMFePIsc28P.ttf",
+  "data/fonts/felltypes/IMFeFCsc28P.ttf",
+  "data/fonts/felltypes/IMFeFCit28P.ttf",
+  "data/fonts/bokor/Bokor.ttf",
+  "data/fonts/didactgothic/DidactGothic.ttf",
+  "data/fonts/allerta/Allerta-Medium.ttf",
+  "data/fonts/allerta/Allerta-Stencil.ttf",
+  "data/fonts/buda/Buda-Light.ttf",
+  "data/fonts/brawler/Brawler-Regular.ttf",
+  "data/fonts/carterone/CarterOne.ttf",
+  "data/fonts/candal/Candal.ttf",
+  "data/fonts/dorsa/Dorsa-Regular.ttf",
+  "data/fonts/crimson/CrimsonText-BoldItalic.ttf",
+  "data/fonts/crimson/CrimsonText-Bold.ttf",
+  "data/fonts/crimson/CrimsonText-Italic.ttf",
+  "data/fonts/crimson/CrimsonText-Roman.ttf",
+  "data/fonts/crimson/CrimsonText-Semibold.ttf",
+  "data/fonts/crimson/CrimsonText-SemiboldItalic.ttf",
+  "data/fonts/amaranth/Amaranth-Italic.ttf",
+  "data/fonts/amaranth/Amaranth-Bold.ttf",
+  "data/fonts/amaranth/Amaranth-Regular.ttf",
+  "data/fonts/amaranth/Amaranth-BoldItalic.ttf",
+  "data/fonts/crushed/Crushed.ttf",
+  "data/fonts/adamina/Adamina-Regular.ttf",
+  "data/fonts/aldrich/Aldrich-Regular.ttf",
+  "data/fonts/fanwoodtext/FanwoodText-Italic.ttf",
+  "data/fonts/fanwoodtext/FanwoodText-Regular.ttf",
+  "data/fonts/anonymouspro/AnonymousPro-Regular.ttf",
+  "data/fonts/anonymouspro/AnonymousPro-Bold.ttf",
+  "data/fonts/anonymouspro/AnonymousPro-Italic.ttf",
+  "data/fonts/anonymouspro/AnonymousPro-BoldItalic.ttf",
+  "data/fonts/bevan/Bevan.ttf",
+  "data/fonts/artifika/Artifika-Regular.ttf",
+  "data/fonts/anton/Anton.ttf",
+  "data/fonts/battambang/Battambang-Regular.ttf",
+  "data/fonts/battambang/Battambang-Bold.ttf",
+  "data/fonts/carme/Carme-Regular.ttf",
+  "data/fonts/cherrycreamsoda/CherryCreamSoda.ttf",
+  "data/fonts/deliusunicase/DeliusUnicase-Regular.ttf",
+  "data/fonts/comingsoon/ComingSoon.ttf",
+  "data/fonts/freehand/Freehand.ttf",
+  "data/fonts/alice/Alice-Regular.ttf",
+  "data/fonts/contrail/Contrail-Regular.ttf",
+  "data/fonts/cardo/Cardo-Bold.ttf",
+  "data/fonts/cardo/Cardo-Italic.ttf",
+  "data/fonts/cardo/Cardo-Regular.ttf",
+  "data/fonts/asset/Asset.ttf",
+  "data/fonts/changaone/ChangaOne-Regular.ttf",
+  "data/fonts/aclonica/Aclonica.ttf",
+  "data/fonts/craftygirls/CraftyGirls.ttf",
+  "data/fonts/architectsdaughter/ArchitectsDaughter.ttf",
+  "data/fonts/content/Content-Bold.ttf",
+  "data/fonts/content/Content-Regular.ttf",
+  "data/fonts/abel/Abel-Regular.ttf",
+  "data/fonts/cuprum/Cuprum.ttf",
+  "data/fonts/andika/Andika-R.ttf"
+};
+}  // namespace cmap_test_data
+}  // namespace sfntly
+
+#endif  // TYPOGRAPHY_FONT_SFNTLY_SRC_TEST_AUTOGENERATED_CMAP_TEST_DATA_H_
diff --git a/test/bitmap_table_test.cc b/test/bitmap_table_test.cc
new file mode 100644
index 0000000..df3ffc0
--- /dev/null
+++ b/test/bitmap_table_test.cc
@@ -0,0 +1,209 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "gtest/gtest.h"
+#include "sfntly/font.h"
+#include "sfntly/port/file_input_stream.h"
+#include "sfntly/port/memory_input_stream.h"
+#include "sfntly/port/memory_output_stream.h"
+#include "sfntly/table/bitmap/ebdt_table.h"
+#include "sfntly/table/bitmap/eblc_table.h"
+#include "sfntly/table/bitmap/index_sub_table_format3.h"
+#include "sfntly/table/bitmap/index_sub_table_format4.h"
+#include "test/test_data.h"
+#include "test/test_font_utils.h"
+
+namespace sfntly {
+
+const int32_t NUM_STRIKES = 4;
+const int32_t STRIKE1_ARRAY_OFFSET = 0xc8;
+const int32_t STRIKE1_INDEX_TABLE_SIZE = 0x4f4;
+const int32_t STRIKE1_NUM_INDEX_TABLES = 1;
+const int32_t STRIKE1_COLOR_REF = 0;
+const int32_t STRIKE1_START_GLYPH_INDEX = 0;
+const int32_t STRIKE1_END_GLYPH_INDEX = 623;
+const int32_t STRIKE1_PPEM_X = 10;
+const int32_t STRIKE1_PPEM_Y = 10;
+const int32_t STRIKE1_BIT_DEPTH = 1;
+const int32_t STRIKE1_FLAGS = 0x01;
+
+const int32_t STRIKE4_SUB1_INDEX_FORMAT = 3;
+const int32_t STRIKE4_SUB1_IMAGE_FORMAT = 1;
+const int32_t STRIKE4_SUB1_IMAGE_DATA_OFFSET = 0x00005893;
+const int32_t STRIKE4_SUB1_GLYPH_OFFSET[] = {
+    0x00005893, 0x00005898, 0x0000589d, 0x000058a2, 0x000058a7,
+    0x000058b2, 0x000058c2, 0x000058d0, 0x000058de, 0x000058e6 };
+const int32_t NUM_STRIKE4_SUB1_GLYPH_OFFSET = 10;
+const int32_t STRIKE4_SUB1_GLYPH2_LENGTH = 0x58a2 - 0x589d;
+
+bool CommonReadingTest(Font* raw_font) {
+  FontPtr font = raw_font;
+
+  EblcTablePtr bitmap_loca = down_cast<EblcTable*>(font->GetTable(Tag::EBLC));
+  EbdtTablePtr bitmap_table = down_cast<EbdtTable*>(font->GetTable(Tag::EBDT));
+
+  EXPECT_FALSE(bitmap_loca == NULL);
+  EXPECT_FALSE(bitmap_table == NULL);
+
+  EXPECT_EQ(bitmap_loca->NumSizes(), NUM_STRIKES);
+
+  // Strike 1
+  BitmapSizeTablePtr strike1 = bitmap_loca->GetBitmapSizeTable(0);
+  EXPECT_FALSE(strike1 == NULL);
+  EXPECT_EQ(strike1->IndexSubTableArrayOffset(), STRIKE1_ARRAY_OFFSET);
+  EXPECT_EQ(strike1->NumberOfIndexSubTables(), STRIKE1_NUM_INDEX_TABLES);
+  EXPECT_EQ(strike1->ColorRef(), STRIKE1_COLOR_REF);
+  EXPECT_EQ(strike1->StartGlyphIndex(), STRIKE1_START_GLYPH_INDEX);
+  EXPECT_EQ(strike1->EndGlyphIndex(), STRIKE1_END_GLYPH_INDEX);
+  EXPECT_EQ(strike1->PpemX(), STRIKE1_PPEM_X);
+  EXPECT_EQ(strike1->PpemY(), STRIKE1_PPEM_Y);
+  EXPECT_EQ(strike1->BitDepth(), STRIKE1_BIT_DEPTH);
+  EXPECT_EQ(strike1->FlagsAsInt(), STRIKE1_FLAGS);
+
+  // Strike 4
+  // In this test font, all strikes and all subtables have same glyphs.
+  BitmapSizeTablePtr strike4 = bitmap_loca->GetBitmapSizeTable(3);
+  EXPECT_FALSE(strike4 == NULL);
+  EXPECT_EQ(strike4->StartGlyphIndex(), STRIKE1_START_GLYPH_INDEX);
+  EXPECT_EQ(strike4->EndGlyphIndex(), STRIKE1_END_GLYPH_INDEX);
+  IndexSubTablePtr sub1 = strike4->GetIndexSubTable(0);
+  EXPECT_FALSE(sub1 == NULL);
+  EXPECT_EQ(sub1->image_format(), STRIKE4_SUB1_IMAGE_FORMAT);
+  EXPECT_EQ(sub1->first_glyph_index(), STRIKE1_START_GLYPH_INDEX);
+  EXPECT_EQ(sub1->last_glyph_index(), STRIKE1_END_GLYPH_INDEX);
+  EXPECT_EQ(sub1->image_data_offset(), STRIKE4_SUB1_IMAGE_DATA_OFFSET);
+
+  for (int32_t i = 0; i < NUM_STRIKE4_SUB1_GLYPH_OFFSET; ++i) {
+      EXPECT_EQ(sub1->GlyphOffset(i), STRIKE4_SUB1_GLYPH_OFFSET[i]);
+  }
+  return true;
+}
+
+bool TestReadingBitmapTable() {
+  FontFactoryPtr factory;
+  factory.Attach(FontFactory::GetInstance());
+  FontArray font_array;
+  LoadFont(SAMPLE_BITMAP_FONT, factory, &font_array);
+  FontPtr font = font_array[0];
+  EXPECT_TRUE(CommonReadingTest(font));
+
+  EblcTablePtr bitmap_loca = down_cast<EblcTable*>(font->GetTable(Tag::EBLC));
+  BitmapSizeTablePtr strike1 = bitmap_loca->GetBitmapSizeTable(0);
+  BitmapSizeTablePtr strike4 = bitmap_loca->GetBitmapSizeTable(3);
+  IndexSubTablePtr sub1 = strike4->GetIndexSubTable(0);
+
+  EXPECT_EQ(strike1->IndexTableSize(), STRIKE1_INDEX_TABLE_SIZE);
+  EXPECT_EQ(sub1->index_format(), STRIKE4_SUB1_INDEX_FORMAT);
+
+  // Strike 4 Index Sub Table 1 is a Format 3
+  IndexSubTableFormat3Ptr sub3 =
+      down_cast<IndexSubTableFormat3*>(strike4->GetIndexSubTable(0));
+  EXPECT_FALSE(sub3 == NULL);
+  BitmapGlyphInfoPtr info;
+  info.Attach(sub3->GlyphInfo(2));
+  EXPECT_EQ(info->glyph_id(), 2);
+  EXPECT_EQ(info->block_offset(), STRIKE4_SUB1_IMAGE_DATA_OFFSET);
+  EXPECT_EQ(info->start_offset(),
+            STRIKE4_SUB1_GLYPH_OFFSET[2] - STRIKE4_SUB1_GLYPH_OFFSET[0]);
+  EXPECT_EQ(info->format(), STRIKE4_SUB1_IMAGE_FORMAT);
+  EXPECT_EQ(info->length(), STRIKE4_SUB1_GLYPH2_LENGTH);
+
+  return true;
+}
+
+// Function in subset_impl.cc
+extern
+void SubsetEBLC(EblcTable::Builder* eblc, const BitmapLocaList& new_loca);
+
+bool TestIndexFormatConversion() {
+  FontFactoryPtr factory;
+  factory.Attach(FontFactory::GetInstance());
+  FontBuilderArray builder_array;
+  BuilderForFontFile(SAMPLE_BITMAP_FONT, factory, &builder_array);
+
+  FontBuilderPtr font_builder;
+  font_builder = builder_array[0];
+  EblcTableBuilderPtr eblc_builder =
+      down_cast<EblcTable::Builder*>(font_builder->GetTableBuilder(Tag::EBLC));
+  BitmapLocaList new_loca;
+  eblc_builder->GenerateLocaList(&new_loca);
+  SubsetEBLC(eblc_builder, new_loca);  // Format 3 -> 4
+
+  FontPtr new_font;
+  new_font.Attach(font_builder->Build());
+
+  // Serialize and reload the serialized font.
+  MemoryOutputStream os;
+  factory->SerializeFont(new_font, &os);
+
+#if defined (SFNTLY_DEBUG_BITMAP)
+  SerializeToFile(&os, "anon-mod.ttf");
+#endif
+
+  MemoryInputStream is;
+  is.Attach(os.Get(), os.Size());
+  FontArray font_array;
+  factory->LoadFonts(&is, &font_array);
+  new_font = font_array[0];
+
+  EXPECT_TRUE(CommonReadingTest(new_font));
+
+  // Strike 4 Index Sub Table 1 is a Format 4
+  EblcTablePtr bitmap_loca =
+      down_cast<EblcTable*>(new_font->GetTable(Tag::EBLC));
+  BitmapSizeTablePtr strike4 = bitmap_loca->GetBitmapSizeTable(3);
+  IndexSubTableFormat4Ptr sub4 =
+      down_cast<IndexSubTableFormat4*>(strike4->GetIndexSubTable(0));
+  EXPECT_FALSE(sub4 == NULL);
+
+  // And this subtable shall have exactly the same offset as original table
+  // since no subsetting happens.
+  FontArray original_font_array;
+  LoadFont(SAMPLE_BITMAP_FONT, factory, &original_font_array);
+  FontPtr font = original_font_array[0];
+  EXPECT_FALSE(font == NULL);
+  EblcTablePtr original_loca = down_cast<EblcTable*>(font->GetTable(Tag::EBLC));
+  EXPECT_FALSE(original_loca == NULL);
+  BitmapSizeTablePtr original_strike4 = bitmap_loca->GetBitmapSizeTable(3);
+  EXPECT_FALSE(original_strike4 == NULL);
+  IndexSubTableFormat3Ptr sub3 =
+      down_cast<IndexSubTableFormat3*>(strike4->GetIndexSubTable(0));
+  EXPECT_FALSE(sub3 == NULL);
+  EXPECT_EQ(strike4->StartGlyphIndex(), original_strike4->StartGlyphIndex());
+  EXPECT_EQ(strike4->EndGlyphIndex(), original_strike4->EndGlyphIndex());
+  for (int32_t i = strike4->StartGlyphIndex();
+               i <= strike4->EndGlyphIndex(); ++i) {
+    BitmapGlyphInfoPtr info, original_info;
+    info.Attach(sub4->GlyphInfo(i));
+    original_info.Attach(sub3->GlyphInfo(i));
+    EXPECT_EQ(info->format(), original_info->format());
+    EXPECT_EQ(info->glyph_id(), original_info->glyph_id());
+    EXPECT_EQ(info->length(), original_info->length());
+    EXPECT_EQ(info->offset(), original_info->offset());
+  }
+
+  return true;
+}
+
+}  // namespace sfntly
+
+TEST(BitmapTable, Reading) {
+  ASSERT_TRUE(sfntly::TestReadingBitmapTable());
+}
+
+TEST(BitmapTable, IndexFormatConversion) {
+  ASSERT_TRUE(sfntly::TestIndexFormatConversion());
+}
diff --git a/test/byte_array_test.cc b/test/byte_array_test.cc
new file mode 100644
index 0000000..40a6489
--- /dev/null
+++ b/test/byte_array_test.cc
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+
+#include "gtest/gtest.h"
+#include "sfntly/data/memory_byte_array.h"
+#include "sfntly/data/growable_memory_byte_array.h"
+
+namespace sfntly {
+namespace byte_array_test {
+
+const int32_t BYTE_ARRAY_SIZES[] =
+    {1, 7, 127, 128, 129, 255, 256, 257, 666, 1023, 10000, 0xffff, 0x10000};
+
+void FillTestByteArray(ByteArray* ba, int32_t size) {
+  for (int32_t i = 0; i < size; ++i) {
+    ba->Put(i, (byte_t)(i % 256));
+  }
+}
+
+void ReadByteArrayWithBuffer(ByteArray* ba, ByteVector* buffer, ByteVector* b) {
+  b->resize(ba->Length());
+  int32_t index = 0;
+  while (index < ba->Length()) {
+    int32_t bytes_read = ba->Get(index, buffer);
+    std::copy(buffer->begin(), buffer->begin() + bytes_read,
+              b->begin() + index);
+    index += bytes_read;
+  }
+}
+
+void ReadByteArrayWithSlidingWindow(ByteArray* ba, int window_size,
+                                    ByteVector* b) {
+  b->resize(ba->Length());
+  int32_t index = 0;
+  int32_t actual_window_size = window_size;
+  while (index < ba->Length()) {
+    actual_window_size =
+        std::min<int32_t>(actual_window_size, b->size() - index);
+    int32_t bytes_read = ba->Get(index, &((*b)[0]), index, actual_window_size);
+    index += bytes_read;
+  }
+}
+
+bool ReadComparison(ByteArray* ba1, ByteArray* ba2) {
+  // single byte reads
+  for (int i = 0; i < ba1->Length(); ++i) {
+    EXPECT_EQ(ba1->Get(i), ba2->Get(i));
+  }
+
+  ByteVector b1, b2;
+  // buffer reads
+  int increments = std::max<int32_t>(ba1->Length() / 11, 1);
+  for (int buffer_size = 1; buffer_size < ba1->Length();
+       buffer_size += increments) {
+    ByteVector buffer(buffer_size);
+    ReadByteArrayWithBuffer(ba1, &buffer, &b1);
+    ReadByteArrayWithBuffer(ba2, &buffer, &b2);
+    EXPECT_GT(b1.size(), static_cast<size_t>(0));
+    EXPECT_EQ(b1.size(), b2.size());
+    EXPECT_TRUE(std::equal(b1.begin(), b1.end(), b2.begin()));
+  }
+
+  // sliding window reads
+  b1.clear();
+  b2.clear();
+  for (int window_size = 1; window_size < ba1->Length();
+       window_size += increments) {
+    ReadByteArrayWithSlidingWindow(ba1, window_size, &b1);
+    ReadByteArrayWithSlidingWindow(ba2, window_size, &b2);
+    EXPECT_GT(b1.size(), static_cast<size_t>(0));
+    EXPECT_EQ(b1.size(), b2.size());
+    EXPECT_TRUE(std::equal(b1.begin(), b1.end(), b2.begin()));
+  }
+
+  return true;
+}
+
+bool CopyTest(ByteArray* ba) {
+  ByteArrayPtr fixed_copy = new MemoryByteArray(ba->Length());
+  ba->CopyTo(fixed_copy);
+  EXPECT_EQ(ba->Length(), fixed_copy->Length());
+  EXPECT_TRUE(ReadComparison(ba, fixed_copy));
+
+  ByteArrayPtr growable_copy = new GrowableMemoryByteArray();
+  ba->CopyTo(growable_copy);
+  EXPECT_EQ(ba->Length(), growable_copy->Length());
+  EXPECT_TRUE(ReadComparison(ba, growable_copy));
+
+  return true;
+}
+
+bool ByteArrayTester(ByteArray* ba) {
+  return CopyTest(ba);
+}
+
+}  // namespace byte_array_test
+
+bool TestMemoryByteArray() {
+  fprintf(stderr, "fixed mem: size ");
+  for (size_t i = 0;
+       i < sizeof(byte_array_test::BYTE_ARRAY_SIZES) / sizeof(int32_t); ++i) {
+    int32_t size = byte_array_test::BYTE_ARRAY_SIZES[i];
+    fprintf(stderr, "%d ", size);
+    ByteArrayPtr ba = new MemoryByteArray(size);
+    byte_array_test::FillTestByteArray(ba, size);
+    EXPECT_TRUE(byte_array_test::ByteArrayTester(ba));
+  }
+  fprintf(stderr, "\n");
+  return true;
+}
+
+bool TestGrowableMemoryByteArray() {
+  fprintf(stderr, "growable mem: size ");
+  for (size_t i = 0;
+       i < sizeof(byte_array_test::BYTE_ARRAY_SIZES) / sizeof(int32_t); ++i) {
+    int32_t size = byte_array_test::BYTE_ARRAY_SIZES[i];
+    fprintf(stderr, "%d ", size);
+    ByteArrayPtr ba = new GrowableMemoryByteArray();
+    byte_array_test::FillTestByteArray(ba, size);
+    EXPECT_TRUE(byte_array_test::ByteArrayTester(ba));
+  }
+  fprintf(stderr, "\n");
+  return true;
+}
+
+}  // namespace sfntly
+
+TEST(ByteArray, All) {
+  ASSERT_TRUE(sfntly::TestMemoryByteArray());
+  ASSERT_TRUE(sfntly::TestGrowableMemoryByteArray());
+}
diff --git a/test/chrome_subsetter.cc b/test/chrome_subsetter.cc
new file mode 100644
index 0000000..9563ab1
--- /dev/null
+++ b/test/chrome_subsetter.cc
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "gtest/gtest.h"
+#include "sample/chromium/font_subsetter.h"
+#include "test/test_data.h"
+#include "test/test_font_utils.h"
+
+namespace {
+  // Use an additional variable to easily change name for testing.
+  const char* kInputFileName = sfntly::SAMPLE_TTF_FILE;
+  const char* kFontName = "Tuffy";
+  const char* kOutputFileName = "tuffy-s.ttf";
+  // The subset we want: Hello, world!
+  // The array is unsorted to verify that the subsetter gets the glyph id
+  // correctly.
+  const unsigned int kGlyphIds[] = { 43, 72, 79, 82, 15, 3, 90, 85, 71, 4 };
+  const unsigned int kGlyphIdsCount = sizeof(kGlyphIds) / sizeof(unsigned int);
+}
+
+// This function is deliberately located at global namespace.
+bool TestChromeSubsetter() {
+  sfntly::ByteVector input_buffer;
+  sfntly::LoadFile(kInputFileName, &input_buffer);
+  EXPECT_GT(input_buffer.size(), (size_t)0);
+
+  unsigned char* output_buffer = NULL;
+  int output_length =
+      SfntlyWrapper::SubsetFont(kFontName,
+                                &(input_buffer[0]),
+                                input_buffer.size(),
+                                kGlyphIds,
+                                kGlyphIdsCount,
+                                &output_buffer);
+
+  EXPECT_GT(output_length, 0);
+
+  if (output_length > 0) {
+    FILE* output_file = NULL;
+#if defined WIN32
+    fopen_s(&output_file, kOutputFileName, "wb");
+#else
+    output_file = fopen(kOutputFileName, "wb");
+#endif
+    EXPECT_TRUE((output_file != NULL));
+    if (output_file) {
+      int byte_count = fwrite(output_buffer, 1, output_length, output_file);
+      EXPECT_EQ(byte_count, output_length);
+      fflush(output_file);
+      fclose(output_file);
+    }
+
+    delete[] output_buffer;
+    return true;
+  }
+
+  return false;
+}
+
+TEST(ChromeSubsetter, All) {
+  EXPECT_TRUE(TestChromeSubsetter());
+}
diff --git a/test/cmap_editing_test.cc b/test/cmap_editing_test.cc
new file mode 100644
index 0000000..6df2720
--- /dev/null
+++ b/test/cmap_editing_test.cc
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include <map>
+#include <algorithm>
+
+#include "sfntly/font.h"
+#include "sfntly/font_factory.h"
+#include "sfntly/table/core/font_header_table.h"
+#include "sfntly/tag.h"
+#include "sfntly/data/memory_byte_array.h"
+#include "sfntly/port/endian.h"
+#include "sfntly/port/file_input_stream.h"
+#include "sfntly/port/memory_output_stream.h"
+#include "test/test_data.h"
+#include "test/test_font_utils.h"
+#include "sfntly/table/core/cmap_table.h"
+#include "sfntly/port/refcount.h"
+#include "gtest/gtest.h"
+
+namespace sfntly {
+TEST(CMapEditingTest, RemoveAllButOneCMap) {
+  FontBuilderArray builders;
+  FontFactoryPtr font_factory;
+  font_factory.Attach(FontFactory::GetInstance());
+  BuilderForFontFile(SAMPLE_TTF_FILE, font_factory, &builders);
+  ASSERT_FALSE(builders.empty());
+  FontBuilderPtr font_builder = builders[0];
+  Ptr<CMapTable::Builder> cmap_table_builder =
+      (CMapTable::Builder*)font_builder->GetTableBuilder(Tag::cmap);
+  ASSERT_NE(cmap_table_builder, reinterpret_cast<CMapTable::Builder*>(NULL));
+  CMapTable::CMapBuilderMap*
+      cmap_builders = cmap_table_builder->GetCMapBuilders();
+  ASSERT_FALSE(cmap_builders->empty());
+
+  for (CMapTable::CMapBuilderMap::iterator
+           it = cmap_builders->begin(); it != cmap_builders->end();) {
+    if (it->second->cmap_id() == CMapTable::WINDOWS_BMP) {
+      ++it;
+    } else {
+      cmap_builders->erase(it++);
+    }
+  }
+  ASSERT_EQ(cmap_builders->size(), (uint32_t)1);
+  Font* font = font_builder->Build();
+  CMapTablePtr cmap_table = down_cast<CMapTable*>(font->GetTable(Tag::cmap));
+  ASSERT_EQ(1, cmap_table->NumCMaps());
+  CMapTable::CMapPtr cmap;
+  cmap.Attach(cmap_table->GetCMap(CMapTable::WINDOWS_BMP));
+  ASSERT_EQ(CMapTable::WINDOWS_BMP, cmap->cmap_id());
+  delete font;
+}
+
+TEST(CMapEditingTest, CopyAllCMapsToNewFont) {
+  FontArray fonts;
+  FontFactoryPtr font_factory;
+  font_factory.Attach(FontFactory::GetInstance());
+  LoadFont(SAMPLE_TTF_FILE, font_factory, &fonts);
+
+  ASSERT_FALSE(fonts.empty());
+  ASSERT_FALSE(fonts[0] == NULL);
+  FontPtr font = fonts[0];
+  CMapTablePtr cmap_table = down_cast<CMapTable*>(font->GetTable(Tag::cmap));
+  FontBuilderPtr font_builder;
+  font_builder.Attach(font_factory->NewFontBuilder());
+  Ptr<CMapTable::Builder> cmap_table_builder =
+      (CMapTable::Builder*)font_builder->NewTableBuilder(Tag::cmap);
+
+  CMapTable::CMapIterator cmap_iter(cmap_table, NULL);
+  while (cmap_iter.HasNext()) {
+    CMapTable::CMapPtr cmap;
+    cmap.Attach(cmap_iter.Next());
+    if (!cmap)
+      continue;
+    cmap_table_builder->NewCMapBuilder(cmap->cmap_id(), cmap->ReadFontData());
+  }
+
+  FontPtr new_font;
+  new_font.Attach(font_builder->Build());
+  CMapTablePtr new_cmap_table =
+      down_cast<CMapTable*>(font->GetTable(Tag::cmap));
+  ASSERT_EQ(cmap_table->NumCMaps(), new_cmap_table->NumCMaps());
+  CMapTable::CMapPtr cmap;
+  cmap.Attach(cmap_table->GetCMap(CMapTable::WINDOWS_BMP));
+  ASSERT_NE(cmap, reinterpret_cast<CMapTable::CMap*>(NULL));
+  ASSERT_EQ(CMapTable::WINDOWS_BMP, cmap->cmap_id());
+}
+}
diff --git a/test/cmap_iterator_test.cc b/test/cmap_iterator_test.cc
new file mode 100644
index 0000000..2e8e6fe
--- /dev/null
+++ b/test/cmap_iterator_test.cc
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include <string.h>
+
+#include <vector>
+#include <string>
+#include <algorithm>
+
+#include "sfntly/font.h"
+#include "sfntly/font_factory.h"
+#include "sfntly/table/core/cmap_table.h"
+#include "sfntly/tag.h"
+#include "sfntly/port/type.h"
+#include "sfntly/port/refcount.h"
+#include "test/test_data.h"
+#include "test/test_font_utils.h"
+
+#include "gtest/gtest.h"
+
+#if GTEST_HAS_PARAM_TEST
+
+namespace sfntly {
+using ::testing::TestWithParam;
+using ::testing::Values;
+
+typedef std::vector<bool> BitSet;
+
+class CMapIteratorTestCase {
+ public:
+  CMapIteratorTestCase(int32_t platform_id, int32_t encoding_id,
+                       const char* file_name)
+      : platform_id_(platform_id),
+        encoding_id_(encoding_id),
+        file_name_(file_name) {
+  }
+  ~CMapIteratorTestCase() {}
+  int32_t platform_id() const { return platform_id_; }
+  int32_t encoding_id() const { return encoding_id_; }
+  const char* file_name() const { return file_name_; }
+
+ private:
+  int32_t platform_id_;
+  int32_t encoding_id_;
+  const char* file_name_;
+};
+
+class CMapIteratorTests
+    : public ::testing::TestWithParam<CMapIteratorTestCase> {
+ public:
+  virtual void SetUp();
+  virtual void TearDown() {}
+
+  BitSet* GenerateCMapEntries(int32_t start, int32_t count);
+  int32_t CompareCMapIterAndBitSet(CMapTable::CMap::CharacterIterator*
+                                   character_iterator,
+                                   BitSet* bit_set);
+
+  Ptr<CMapTable::CMap> cmap_;
+};
+
+void CMapIteratorTests::SetUp() {
+  FontArray fonts;
+  Ptr<FontFactory> font_factory;
+  const char* file_name = GetParam().file_name();
+  LoadFont(file_name, font_factory, &fonts);
+  Ptr<Font> font;
+  font.Attach(fonts[0].Detach());
+  Ptr<CMapTable> cmap_table = down_cast<CMapTable*>(font->GetTable(Tag::cmap));
+  ASSERT_FALSE(cmap_table == NULL);
+  cmap_.Attach(cmap_table->GetCMap(GetParam().platform_id(),
+                                   GetParam().encoding_id()));
+  ASSERT_FALSE(cmap_ == NULL);
+}
+
+BitSet* CMapIteratorTests::GenerateCMapEntries(int32_t start, int32_t count) {
+  BitSet* entries = new BitSet(count);
+  for (int32_t c = start; c < start + count; ++c) {
+    int32_t g = cmap_->GlyphId(c);
+    if (g != CMapTable::NOTDEF)
+      (*entries)[c] = true;
+  }
+  return entries;
+}
+
+int32_t
+CMapIteratorTests::
+CompareCMapIterAndBitSet(CMapTable::CMap::CharacterIterator* character_iterator,
+                         BitSet* bit_set) {
+  int32_t iterator_not_bitset_count = 0;
+  BitSet::iterator end = bit_set->end(),
+      beginning = bit_set->begin(),
+      init_beginning = beginning,
+      current = std::find(beginning, end, true);
+  for (int32_t next_bit = current - beginning;
+       character_iterator->HasNext() && current != end;
+       next_bit = current - init_beginning) {
+    int32_t c = character_iterator->Next();
+    EXPECT_TRUE(c <= next_bit || current == end);
+    if (!(c <= next_bit || current == end))
+      return -1;
+    if (c == next_bit) {
+      beginning = current + 1;
+      current = std::find(beginning, end, true);
+    } else {
+      iterator_not_bitset_count++;
+    }
+  }
+  EXPECT_EQ(end, current);
+#if defined (SFNTLY_DEBUG_CMAP)
+  fprintf(stderr, "%s %d: Differences between iterator and bitset: %d\n",
+          cmap_->format(), GetParam().file_name(), iterator_not_bitset_count);
+#endif
+  return iterator_not_bitset_count;
+}
+
+TEST_P(CMapIteratorTests, IteratorTest) {
+  BitSet* bit_set = GenerateCMapEntries(0, 0x10ffff);
+  CMapTable::CMap::CharacterIterator* character_iterator = NULL;
+  character_iterator = cmap_->Iterator();
+  EXPECT_NE(character_iterator,
+            reinterpret_cast<CMapTable::CMap::CharacterIterator*>(NULL));
+  CompareCMapIterAndBitSet(character_iterator, bit_set);
+  delete character_iterator;
+  delete bit_set;
+}
+
+CMapIteratorTestCase kCMapIteratorTestsTestCases[] = {
+  CMapIteratorTestCase(CMapTable::WINDOWS_BMP.platform_id,
+                       CMapTable::WINDOWS_BMP.encoding_id,
+                       SAMPLE_TTF_FILE)
+};
+
+INSTANTIATE_TEST_CASE_P(CMapIteratorTests,
+                        CMapIteratorTests,
+                        ::testing::ValuesIn(kCMapIteratorTestsTestCases));
+}
+
+#else
+
+TEST(DummyTest, ValueParameterizedTestsAreNotSupportedOnThisPlatform) {}
+
+#endif  // GTEST_HAS_PARAM
diff --git a/test/cmap_test.cc b/test/cmap_test.cc
new file mode 100644
index 0000000..02bf8a2
--- /dev/null
+++ b/test/cmap_test.cc
@@ -0,0 +1,213 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/port/type.h"
+#include <assert.h>
+#include <unicode/ucnv.h>
+
+#include <string>
+#include <iostream>
+
+#include "gtest/gtest.h"
+#include "sfntly/font.h"
+#include "sfntly/font_factory.h"
+#include "sfntly/table/core/cmap_table.h"
+#include "sfntly/data/memory_byte_array.h"
+#include "sfntly/table/core/font_header_table.h"
+#include "sfntly/tag.h"
+
+#include "test/test_utils.h"
+#include "test/test_font_utils.h"
+#include "test/test_data.h"
+
+#if GTEST_HAS_PARAM_TEST
+
+namespace sfntly {
+using ::testing::TestWithParam;
+using ::testing::Values;
+
+class CMapTestCase {
+ public:
+  CMapTestCase(const char* font_name,
+               int32_t first_platform_id,
+               int32_t first_encoding_id,
+               const char* first_charset_name,
+               int32_t second_platform_id,
+               int32_t second_encoding_id,
+               const char* second_charset_name,
+               int32_t low_char,
+               int32_t high_char)
+      : font_name_(font_name),
+        first_platform_id_(first_platform_id),
+        first_encoding_id_(first_encoding_id),
+        first_charset_name_(first_charset_name),
+        second_platform_id_(second_platform_id),
+        second_encoding_id_(second_encoding_id),
+        second_charset_name_(second_charset_name),
+        low_char_(low_char),
+        high_char_(high_char) {
+  }
+
+  const char* font_name() const { return font_name_; }
+  int32_t first_platform_id() const { return first_platform_id_; }
+  int32_t first_encoding_id() const { return first_encoding_id_; }
+  const char* first_charset_name() const { return first_charset_name_; }
+  int32_t second_platform_id() const { return second_platform_id_; }
+  int32_t second_encoding_id() const { return second_encoding_id_; }
+  const char* second_charset_name() const { return second_charset_name_; }
+  int32_t low_char() const { return low_char_; }
+  int32_t high_char() const { return high_char_; }
+
+ private:
+  const char* font_name_;
+  int32_t first_platform_id_;
+  int32_t first_encoding_id_;
+  const char* first_charset_name_;
+  int32_t second_platform_id_;
+  int32_t second_encoding_id_;
+  const char* second_charset_name_;
+  int32_t low_char_;
+  int32_t high_char_;
+};
+
+class CMapTests : public :: testing::TestWithParam<CMapTestCase> {
+ public:
+  CMapTests() : encoder1_(NULL), encoder2_(NULL), successful_setup_(false) {
+  }
+  virtual void SetUp() {}
+  virtual void TearDown();
+
+  void CommonSetUp(FontArray* font_array);
+
+  void CompareCMaps();
+
+  Ptr<CMapTable::CMap> cmap1_;
+  Ptr<CMapTable::CMap> cmap2_;
+  UConverter* encoder1_;
+  UConverter* encoder2_;
+  bool successful_setup_;
+};
+
+::std::ostream& operator<<(::std::ostream& os, const CMapTestCase *test_case) {
+  return os << "("
+            << test_case->font_name() << ", "
+            << test_case->first_platform_id() << ", "
+            << test_case->first_encoding_id() << ", "
+            << test_case->first_charset_name() << ", "
+            << test_case->second_platform_id() << ", "
+            << test_case->second_encoding_id() << ", "
+            << test_case->second_charset_name() << ", "
+            << test_case->low_char() << ", "
+            << test_case->high_char() << ")";
+}
+
+void CMapTests::CommonSetUp(FontArray* font_array) {
+  ASSERT_NE(font_array, reinterpret_cast<FontArray*>(NULL));
+  ASSERT_FALSE(font_array->empty());
+  Ptr<Font> font;
+  font = font_array->at(0);
+  ASSERT_NE(font, reinterpret_cast<Font*>(NULL));
+  Ptr<CMapTable> cmap_table =
+      down_cast<CMapTable*>(font->GetTable(Tag::cmap));
+  cmap1_.Attach(cmap_table->GetCMap(GetParam().first_platform_id(),
+                                    GetParam().first_encoding_id()));
+  ASSERT_NE((cmap1_), reinterpret_cast<CMapTable::CMap*>(NULL));
+  cmap2_.Attach(cmap_table->GetCMap(GetParam().second_platform_id(),
+                                    GetParam().second_encoding_id()));
+  ASSERT_NE((cmap2_), reinterpret_cast<CMapTable::CMap*>(NULL));
+  encoder1_ = TestUtils::GetEncoder(GetParam().first_charset_name());
+  encoder2_ = TestUtils::GetEncoder(GetParam().second_charset_name());
+  successful_setup_ = true;
+}
+
+void CMapTests::TearDown() {
+  if (encoder1_)
+    ucnv_close(encoder1_);
+  if (encoder2_)
+    ucnv_close(encoder2_);
+}
+
+void CMapTests::CompareCMaps() {
+  ASSERT_TRUE(successful_setup_);
+  for (int32_t uchar = GetParam().low_char();
+       uchar <= GetParam().high_char(); ++uchar) {
+    int32_t c1 = uchar;
+    if (encoder1_ != NULL)
+      c1 = TestUtils::EncodeOneChar(encoder1_, (int16_t)uchar);
+    int32_t c2 = uchar;
+    if (encoder2_ != NULL)
+      c2 = TestUtils::EncodeOneChar(encoder2_, (int16_t)uchar);
+    int32_t glyph_id1 = cmap1_->GlyphId(c1);
+    int32_t glyph_id2 = cmap2_->GlyphId(c2);
+#ifdef SFNTLY_DEBUG_CMAP
+    if (glyph_id1 != glyph_id2)
+      fprintf(stderr, "%x: g1=%x, %x: g2=%x\n", c1, glyph_id1, c2, glyph_id2);
+#endif
+    ASSERT_EQ(glyph_id1, glyph_id2);
+  }
+#ifdef SFNTLY_SFNTLY_DEBUG_CMAPCMAP
+  fprintf(stderr, "\n");
+#endif
+}
+
+TEST_P(CMapTests, GlyphsBetweenCMapsFingerprint) {
+  Ptr<FontFactory> font_factory;
+  font_factory.Attach(FontFactory::GetInstance());
+  font_factory->FingerprintFont(true);
+  FontArray font_array;
+  LoadFont(GetParam().font_name(), font_factory, &font_array);
+  CommonSetUp(&font_array);
+  CompareCMaps();
+}
+
+TEST_P(CMapTests, GlyphsBetweenCMapsNoFingerprint) {
+  Ptr<FontFactory> font_factory;
+  font_factory.Attach(FontFactory::GetInstance());
+  FontArray font_array;
+  LoadFont(GetParam().font_name(), font_factory, &font_array);
+  CommonSetUp(&font_array);
+  CompareCMaps();
+}
+
+TEST_P(CMapTests, GlyphsBetweenCMapsUsingByteVector) {
+  FontArray font_array;
+  LoadFontUsingByteVector(GetParam().font_name(), true, &font_array);
+  CommonSetUp(&font_array);
+  CompareCMaps();
+}
+
+CMapTestCase kCMapTestsTestCases[] = {
+  CMapTestCase(SAMPLE_TTF_FILE,
+               PlatformId::kWindows,
+               WindowsEncodingId::kUnicodeUCS2,
+               NULL,
+               PlatformId::kUnicode,
+               UnicodeEncodingId::kUnicode2_0_BMP,
+               NULL,
+               (int32_t)0x20,
+               (int32_t)0x7f),
+};
+
+INSTANTIATE_TEST_CASE_P(CMapTests,
+                        CMapTests,
+                        ::testing::ValuesIn(kCMapTestsTestCases));
+}
+
+#else
+
+TEST(DummyTest, ValueParameterizedTestsAreNotSupportedOnThisPlatform) {}
+
+#endif  // GTEST_HAS_PARAM
diff --git a/test/endian_test.cc b/test/endian_test.cc
new file mode 100644
index 0000000..0d9da09
--- /dev/null
+++ b/test/endian_test.cc
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "gtest/gtest.h"
+#include "sfntly/tag.h"
+#include "sfntly/data/growable_memory_byte_array.h"
+#include "sfntly/data/writable_font_data.h"
+#include "sfntly/math/fixed1616.h"
+#include "sfntly/port/memory_output_stream.h"
+#include "sfntly/data/font_output_stream.h"
+
+namespace sfntly {
+
+bool TestEndian() {
+  byte_t test_data[] = {
+      0x68, 0x65, 0x61, 0x64,  // 0: head
+      0xca, 0xca, 0xca, 0xca,  // 4: ubyte, byte, char
+      0x00, 0x18, 0x80, 0x18,  // 8: ushort, short
+      0x00, 0x00, 0x18, 0x00,  // 12: uint24
+      0x00, 0x00, 0x00, 0x18,  // 16: ulong
+      0xff, 0xff, 0xff, 0x00,  // 20: long
+      0x00, 0x01, 0x00, 0x00   // 24: fixed
+  };
+
+  ByteArrayPtr ba1 = new GrowableMemoryByteArray();
+  for (size_t i = 0; i < sizeof(test_data); ++i) {
+    ba1->Put(i, test_data[i]);
+  }
+  ReadableFontDataPtr rfd = new ReadableFontData(ba1);
+  EXPECT_EQ(rfd->ReadULongAsInt(0), Tag::head);
+  EXPECT_EQ(rfd->ReadUByte(4), 202);
+  EXPECT_EQ(rfd->ReadByte(5), -54);
+  EXPECT_EQ(rfd->ReadChar(6), 202);
+  EXPECT_EQ(rfd->ReadUShort(8), 24);
+  EXPECT_EQ(rfd->ReadShort(10), -32744);
+  EXPECT_EQ(rfd->ReadUInt24(12), 24);
+  EXPECT_EQ(rfd->ReadULong(16), 24);
+  EXPECT_EQ(rfd->ReadLong(20), -256);
+  EXPECT_EQ(rfd->ReadFixed(24), Fixed1616::Fixed(1, 0));
+
+  MemoryOutputStream os;
+  FontOutputStream fos(&os);
+  fos.WriteULong(Tag::head);
+  fos.Write(202);
+  fos.Write(202);
+  fos.Write(202);
+  fos.Write(202);
+  fos.WriteUShort(24);
+  fos.WriteShort(-32744);
+  fos.WriteUInt24(24);
+  fos.WriteChar(0);
+  fos.WriteULong(24);
+  fos.WriteLong(-256);
+  fos.WriteFixed(Fixed1616::Fixed(1, 0));
+  EXPECT_EQ(memcmp(os.Get(), test_data, sizeof(test_data)), 0);
+
+  return true;
+}
+
+}  // namespace sfntly
+
+TEST(Endian, All) {
+  ASSERT_TRUE(sfntly::TestEndian());
+}
diff --git a/test/file_io_test.cc b/test/file_io_test.cc
new file mode 100644
index 0000000..3cec4d6
--- /dev/null
+++ b/test/file_io_test.cc
@@ -0,0 +1,153 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+
+#include "gtest/gtest.h"
+#include "sfntly/port/file_input_stream.h"
+#include "sfntly/data/font_input_stream.h"
+#include "test/test_data.h"
+
+namespace sfntly {
+
+bool TestFileInputStream() {
+  FILE* file_handle = NULL;
+#if defined (WIN32)
+  fopen_s(&file_handle, SAMPLE_TTF_FILE, "rb");
+#else
+  file_handle = fopen(SAMPLE_TTF_FILE, "rb");
+#endif
+  if (file_handle == NULL) {
+    return false;
+  }
+  fseek(file_handle, 0, SEEK_END);
+  size_t length = ftell(file_handle);
+  fseek(file_handle, 0, SEEK_SET);
+  ByteVector b1;
+  b1.resize(length);
+  size_t bytes_read = fread(&(b1[0]), 1, length, file_handle);
+  EXPECT_EQ(bytes_read, length);
+  fclose(file_handle);
+
+  // Full file reading test
+  FileInputStream is;
+  is.Open(SAMPLE_TTF_FILE);
+  EXPECT_EQ(length, (size_t)is.Available());
+  ByteVector b2;
+  is.Read(&b2, 0, length);
+  is.Close();
+  EXPECT_EQ(memcmp(&(b1[0]), &(b2[0]), length), 0);
+  b2.clear();
+
+  // Partial reading test
+  is.Open(SAMPLE_TTF_FILE);
+  is.Skip(89);
+  is.Read(&b2, 0, 100);
+  EXPECT_EQ(memcmp(&(b1[89]), &(b2[0]), 100), 0);
+  b2.clear();
+
+  // Skip test
+  is.Skip(-89);
+  is.Read(&b2, 0, 100);
+  EXPECT_EQ(memcmp(&(b1[100]), &(b2[0]), 100), 0);
+  b2.clear();
+  is.Skip(100);
+  is.Read(&b2, 0, 100);
+  EXPECT_EQ(memcmp(&(b1[300]), &(b2[0]), 100), 0);
+  is.Skip(-400);
+  b2.clear();
+
+  // Offset test
+  is.Read(&b2, 0, 100);
+  is.Read(&b2, 100, 100);
+  EXPECT_EQ(memcmp(&(b1[0]), &(b2[0]), 200), 0);
+
+  // Unread test
+  ByteVector b3;
+  b3.resize(200);
+  is.Unread(&b3);
+  EXPECT_EQ(memcmp(&(b3[0]), &(b2[0]), 200), 0);
+
+  return true;
+}
+
+bool TestFontInputStreamBasic() {
+  FILE* file_handle = NULL;
+#if defined (WIN32)
+  fopen_s(&file_handle, SAMPLE_TTF_FILE, "rb");
+#else
+  file_handle = fopen(SAMPLE_TTF_FILE, "rb");
+#endif
+  if (file_handle == NULL) {
+    return false;
+  }
+  fseek(file_handle, 0, SEEK_END);
+  size_t length = ftell(file_handle);
+  fseek(file_handle, 0, SEEK_SET);
+  ByteVector b1;
+  b1.resize(length);
+  size_t bytes_read = fread(&(b1[0]), 1, length, file_handle);
+  EXPECT_EQ(bytes_read, length);
+  fclose(file_handle);
+
+  FileInputStream is;
+  is.Open(SAMPLE_TTF_FILE);
+  FontInputStream font_is1(&is);
+  EXPECT_EQ((size_t)font_is1.Available(), length);
+
+  ByteVector b2;
+  font_is1.Read(&b2, 0, length);
+  font_is1.Close();
+  EXPECT_EQ(memcmp(&(b1[0]), &(b2[0]), length), 0);
+  b2.clear();
+
+  is.Open(SAMPLE_TTF_FILE);
+  is.Skip(89);
+  FontInputStream font_is2(&is, 200);
+  font_is2.Read(&b2, 0, 100);
+  EXPECT_EQ(memcmp(&(b1[89]), &(b2[0]), 100), 0);
+  font_is2.Read(&b2, 100, 100);
+  EXPECT_EQ(memcmp(&(b1[89]), &(b2[0]), 200), 0);
+  b2.clear();
+  font_is2.Skip(-200);
+  font_is2.Read(&b2, 0, 100);
+  EXPECT_EQ(memcmp(&(b1[89]), &(b2[0]), 100), 0);
+
+  return true;
+}
+
+bool TestFontInputStreamTableLoading() {
+  FileInputStream is;
+  is.Open(SAMPLE_TTF_FILE);
+  FontInputStream font_is(&is);
+
+  font_is.Skip(TTF_OFFSET[SAMPLE_TTF_FEAT]);
+  FontInputStream gdef_is(&font_is, TTF_LENGTH[SAMPLE_TTF_FEAT]);
+  ByteVector feat_data;
+  gdef_is.Read(&feat_data, 0, TTF_LENGTH[SAMPLE_TTF_FEAT]);
+  EXPECT_EQ(memcmp(&(feat_data[0]), TTF_FEAT_DATA,
+                   TTF_LENGTH[SAMPLE_TTF_FEAT]), 0);
+
+  return true;
+}
+
+}  // namespace sfntly
+
+TEST(FileIO, All) {
+  ASSERT_TRUE(sfntly::TestFileInputStream());
+  ASSERT_TRUE(sfntly::TestFontInputStreamBasic());
+  ASSERT_TRUE(sfntly::TestFontInputStreamTableLoading());
+}
diff --git a/test/font_data_test.cc b/test/font_data_test.cc
new file mode 100644
index 0000000..4b0db64
--- /dev/null
+++ b/test/font_data_test.cc
@@ -0,0 +1,337 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include <vector>
+#include <algorithm>
+
+#include "gtest/gtest.h"
+#include "sfntly/port/type.h"
+#include "sfntly/data/writable_font_data.h"
+#include "sfntly/data/memory_byte_array.h"
+
+namespace sfntly {
+
+const int32_t BYTE_ARRAY_SIZES[] =
+  {1, 7, 127, 128, 129, 255, 256, 257, 666, 1023, 0x10000};
+
+// array data for searching
+const int32_t LOWER_BYTE_ARRAY_FOR_SEARCHING[] = {2, 4, 7, 13, 127};
+const int32_t UPPER_BYTE_ARRAY_FOR_SEARCHING[] = {2, 5, 12, 16, 256};
+const int32_t kLowerByteArrayForSearchingLength = 5;
+const int32_t kUpperByteArrayForSearchingLength = 5;
+
+// search test result pairs - number to search for; index found at
+const int32_t SEARCH_TEST_PAIRS[][2] = {
+  {0, -1}, {1, -1}, {2, 0}, {3, -1}, {4, 1}, {5, 1}, {6, -1}, {12, 2},
+  {13, 3}, {17, -1}, {126, -1}, {127, 4}, {256, 4}, {257, -1}, {0x1000, -1}
+};
+const int32_t kSearchTestPairsLength = 15;
+
+// offset and start index data for searching data
+// array data size, lower_start_index, lower_offset, upper_start_index,
+// upper_offset
+const int32_t SEARCH_TEST_OFFSETS[][5] = {
+  // lower[], upper[]
+  { (kLowerByteArrayForSearchingLength + kUpperByteArrayForSearchingLength)
+    * DataSize::kUSHORT,
+    0,
+    DataSize::kUSHORT,
+    kLowerByteArrayForSearchingLength * DataSize::kUSHORT,
+    DataSize::kUSHORT },
+
+  // {lower, upper} []
+  { (kLowerByteArrayForSearchingLength + kUpperByteArrayForSearchingLength)
+    * DataSize::kUSHORT,
+    0,
+    2 * DataSize::kUSHORT,
+    DataSize::kUSHORT,
+    2 * DataSize::kUSHORT },
+
+  // upper[], lower[]
+  { (kLowerByteArrayForSearchingLength + kUpperByteArrayForSearchingLength)
+    * DataSize::kUSHORT,
+    kLowerByteArrayForSearchingLength * DataSize::kUSHORT,
+    DataSize::kUSHORT,
+    0,
+    DataSize::kUSHORT },
+
+  // {upper, lower} []
+  { (kLowerByteArrayForSearchingLength + kUpperByteArrayForSearchingLength)
+    * DataSize::kUSHORT,
+    DataSize::kUSHORT,
+    2 * DataSize::kUSHORT,
+    0,
+    2 * DataSize::kUSHORT }
+};
+const int32_t kSearchTestOffsetLength = 4;
+
+ReadableFontData*
+FillTestFontDataWithShortsForSearching(WritableFontData* wfd,
+                                       const int32_t* lower_data,
+                                       int32_t lower_start_index,
+                                       int32_t lower_offset,
+                                       const int32_t* upper_data,
+                                       int32_t upper_start_index,
+                                       int32_t upper_offset) {
+  // lower data
+  int offset = lower_start_index;
+  for (int32_t i = 0; i < kLowerByteArrayForSearchingLength; ++i) {
+    wfd->WriteUShort(offset, lower_data[i]);
+    offset += lower_offset;
+  }
+
+  // upper data
+  offset = upper_start_index;
+  for (int32_t i = 0; i < kUpperByteArrayForSearchingLength; ++i) {
+    wfd->WriteUShort(offset, upper_data[i]);
+    offset += upper_offset;
+  }
+
+  return wfd;
+}
+
+bool TestReadableFontDataSearching() {
+  for (int32_t i = 0; i < kSearchTestOffsetLength; ++i) {
+    const int32_t* array_setup_offset = SEARCH_TEST_OFFSETS[i];
+    WritableFontDataPtr wfd;
+    wfd.Attach(WritableFontData::CreateWritableFontData(array_setup_offset[0]));
+    FillTestFontDataWithShortsForSearching(wfd,
+                                           LOWER_BYTE_ARRAY_FOR_SEARCHING,
+                                           array_setup_offset[1],
+                                           array_setup_offset[2],
+                                           UPPER_BYTE_ARRAY_FOR_SEARCHING,
+                                           array_setup_offset[3],
+                                           array_setup_offset[4]);
+    for (int32_t j = 0; j < kSearchTestPairsLength; ++j) {
+      const int32_t* test_case = SEARCH_TEST_PAIRS[j];
+      int32_t found = wfd->SearchUShort(array_setup_offset[1],
+                                        array_setup_offset[2],
+                                        array_setup_offset[3],
+                                        array_setup_offset[4],
+                                        kLowerByteArrayForSearchingLength,
+                                        test_case[0]);
+#if defined (SFNTLY_DEBUG_FONTDATA)
+      fprintf(stderr, "Searching for %d; Got %d; Expected %d; "
+              "[test %d][offset %d]\n",
+              test_case[0], found, test_case[1], j, i);
+#endif
+      EXPECT_EQ(test_case[1], found);
+    }
+  }
+  return true;
+}
+
+void FillTestByteArray(ByteArray* ba, int32_t size) {
+  for (int32_t i = 0; i < size; ++i) {
+    ba->Put(i, (byte_t)(i % 256));
+  }
+}
+
+void ReadFontDataWithSingleByte(ReadableFontData* rfd, ByteVector* buffer) {
+  buffer->resize(rfd->Length());
+  for (int32_t index = 0; index < rfd->Length(); ++index) {
+    (*buffer)[index] = (byte_t)(rfd->ReadByte(index));
+  }
+}
+
+void ReadFontDataWithBuffer(ReadableFontData* rfd,
+                            int32_t buffer_size,
+                            ByteVector* b) {
+  ByteVector buffer(buffer_size);
+  b->resize(rfd->Length());
+
+  int32_t index = 0;
+  while (index < rfd->Length()) {
+    int32_t bytes_read = rfd->ReadBytes(index, &(buffer[0]), 0, buffer.size());
+    EXPECT_GE(bytes_read, 0);
+    std::copy(buffer.begin(), buffer.begin() + bytes_read, b->begin() + index);
+    index += bytes_read;
+  }
+}
+
+void ReadFontDataWithSlidingWindow(ReadableFontData* rfd, int32_t window_size,
+                                   ByteVector* b) {
+  b->resize(rfd->Length());
+  int32_t index = 0;
+  while (index < rfd->Length()) {
+    int32_t actual_window_size =
+        std::min<int32_t>(window_size, b->size() - index);
+    int32_t bytes_read =
+        rfd->ReadBytes(index, &((*b)[0]), index, actual_window_size);
+    EXPECT_GE(bytes_read, 0);
+    index += bytes_read;
+  }
+}
+
+void WriteFontDataWithSingleByte(ReadableFontData* rfd, WritableFontData* wfd) {
+  for (int32_t index = 0; index < rfd->Length(); ++index) {
+    byte_t b = (byte_t)(rfd->ReadByte(index));
+    wfd->WriteByte(index, b);
+  }
+}
+
+void WriteFontDataWithBuffer(ReadableFontData* rfd,
+                             WritableFontData* wfd,
+                             int32_t buffer_size) {
+  ByteVector buffer(buffer_size);
+  int32_t index = 0;
+  while (index < rfd->Length()) {
+    int32_t bytesRead = rfd->ReadBytes(index, &(buffer[0]), 0, buffer.size());
+    wfd->WriteBytes(index, &(buffer[0]), 0, buffer.size());
+    index += bytesRead;
+  }
+}
+
+void WriteFontDataWithSlidingWindow(ReadableFontData* rfd,
+                                    WritableFontData* wfd,
+                                    int32_t window_size) {
+  ByteVector b(rfd->Length());
+  int32_t index = 0;
+  while (index < rfd->Length()) {
+    int32_t sliding_size = std::min<int32_t>(window_size, b.size() - index);
+    int32_t bytes_read = rfd->ReadBytes(index, &(b[0]), index, sliding_size);
+    wfd->WriteBytes(index, &(b[0]), index, sliding_size);
+    index += bytes_read;
+  }
+}
+
+bool ReadComparison(int32_t offset,
+                    int32_t length,
+                    ReadableFontData* rfd1,
+                    ReadableFontData* rfd2) {
+  EXPECT_TRUE(length == rfd2->Length());
+  ByteVector b1, b2;
+  b1.resize(length);
+  b2.resize(length);
+
+  // single byte reads
+  ReadFontDataWithSingleByte(rfd1, &b1);
+  ReadFontDataWithSingleByte(rfd2, &b2);
+  EXPECT_EQ(memcmp(&(b1[offset]), &(b2[0]), length), 0);
+
+  // buffer reads
+  int32_t increments = std::max<int32_t>(length / 11, 1);
+  for (int32_t buffer_size = 1; buffer_size <= length;
+       buffer_size += increments) {
+    b1.clear();
+    b2.clear();
+    b1.resize(length);
+    b2.resize(length);
+    ReadFontDataWithBuffer(rfd1, buffer_size, &b1);
+    ReadFontDataWithBuffer(rfd2, buffer_size, &b2);
+    int result = memcmp(&(b1[offset]), &(b2[0]), length);
+    EXPECT_EQ(result, 0);
+  }
+
+  // sliding window reads
+  for (int32_t window_size = 1; window_size <= length;
+       window_size += increments) {
+    b1.clear();
+    b2.clear();
+    b1.resize(length);
+    b2.resize(length);
+    ReadFontDataWithSlidingWindow(rfd1, window_size, &b1);
+    ReadFontDataWithSlidingWindow(rfd2, window_size, &b2);
+    int result = memcmp(&(b1[offset]), &(b2[0]), length);
+    EXPECT_EQ(result, 0);
+  }
+  return true;
+}
+
+void SlicingReadTest(ReadableFontData* rfd) {
+  fprintf(stderr, "read - trim = ");
+  for (int32_t trim = 0; trim < (rfd->Length() / 2) + 1;
+       trim += (rfd->Length() / 21) + 1) {
+    fprintf(stderr, "%d ", trim);
+    int32_t length = rfd->Length() - 2 * trim;
+    ReadableFontDataPtr slice;
+    slice.Attach(down_cast<ReadableFontData*>(rfd->Slice(trim, length)));
+    EXPECT_TRUE(ReadComparison(trim, length, rfd, slice));
+  }
+  fprintf(stderr, "\n");
+}
+
+void SlicingWriteTest(ReadableFontData* rfd, WritableFontData* wfd) {
+  fprintf(stderr, "write - trim = ");
+  for (int32_t trim = 0; trim < (rfd->Length() / 2) + 1;
+       trim += (rfd->Length() / 21) + 1) {
+    fprintf(stderr, "%d ", trim);
+    int32_t length = rfd->Length() - 2 * trim;
+    WritableFontDataPtr w_slice;
+    ReadableFontDataPtr r_slice;
+
+    // single byte writes
+    w_slice.Attach(down_cast<WritableFontData*>(wfd->Slice(trim, length)));
+    r_slice.Attach(down_cast<ReadableFontData*>(rfd->Slice(trim, length)));
+    WriteFontDataWithSingleByte(r_slice, w_slice);
+    EXPECT_TRUE(ReadComparison(trim, length, rfd, w_slice));
+
+    // buffer writes
+    int32_t increments = std::max<int32_t>(length / 11, 1);
+    for (int32_t buffer_size = 1; buffer_size < length;
+         buffer_size += increments) {
+      w_slice.Attach(down_cast<WritableFontData*>(wfd->Slice(trim, length)));
+      r_slice.Attach(down_cast<ReadableFontData*>(rfd->Slice(trim, length)));
+      WriteFontDataWithBuffer(r_slice, w_slice, buffer_size);
+      EXPECT_TRUE(ReadComparison(trim, length, rfd, w_slice));
+    }
+
+    // sliding window writes
+    for (int window_size = 1; window_size < length; window_size += increments) {
+      w_slice.Attach(down_cast<WritableFontData*>(wfd->Slice(trim, length)));
+      r_slice.Attach(down_cast<ReadableFontData*>(rfd->Slice(trim, length)));
+      WriteFontDataWithSlidingWindow(r_slice, w_slice, window_size);
+      EXPECT_TRUE(ReadComparison(trim, length, rfd, w_slice));
+    }
+  }
+  fprintf(stderr, "\n");
+}
+
+bool TestReadableFontData() {
+  for (size_t i = 0; i < sizeof(BYTE_ARRAY_SIZES) / sizeof(int32_t); ++i) {
+    int32_t size = BYTE_ARRAY_SIZES[i];
+    ByteArrayPtr ba = new MemoryByteArray(size);
+    FillTestByteArray(ba, size);
+    ReadableFontDataPtr rfd = new ReadableFontData(ba);
+    SlicingReadTest(rfd);
+  }
+  return true;
+}
+
+bool TestWritableFontData() {
+  for (size_t i = 0; i < sizeof(BYTE_ARRAY_SIZES) / sizeof(int32_t); ++i) {
+    int32_t size = BYTE_ARRAY_SIZES[i];
+    ByteArrayPtr ba = new MemoryByteArray(size);
+    FillTestByteArray(ba, size);
+    WritableFontDataPtr wfd = new WritableFontData(ba);
+    SlicingReadTest(wfd);
+    ByteArrayPtr temp = new MemoryByteArray(size);
+    WritableFontDataPtr wfd_copy = new WritableFontData(temp);
+    SlicingWriteTest(wfd, wfd_copy);
+  }
+  return true;
+}
+
+}  // namespace sfntly
+
+TEST(FontData, ReadableFontDataSearching) {
+  ASSERT_TRUE(sfntly::TestReadableFontDataSearching());
+}
+
+TEST(FontData, All) {
+  ASSERT_TRUE(sfntly::TestReadableFontData());
+  ASSERT_TRUE(sfntly::TestWritableFontData());
+}
diff --git a/test/font_parsing_test.cc b/test/font_parsing_test.cc
new file mode 100644
index 0000000..6fd5c3b
--- /dev/null
+++ b/test/font_parsing_test.cc
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "gtest/gtest.h"
+
+#include "sfntly/data/font_input_stream.h"
+#include "sfntly/data/memory_byte_array.h"
+#include "sfntly/font.h"
+#include "sfntly/font_factory.h"
+#include "sfntly/table/core/font_header_table.h"
+#include "sfntly/table/table.h"
+#include "sfntly/table/generic_table_builder.h"
+#include "sfntly/table/table_based_table_builder.h"
+#include "sfntly/tag.h"
+#include "sfntly/port/file_input_stream.h"
+#include "test/test_data.h"
+#include "test/test_font_utils.h"
+
+namespace sfntly {
+
+bool TestFontParsing() {
+  ByteVector input_buffer;
+  LoadFile(SAMPLE_TTF_FILE, &input_buffer);
+
+  FontFactoryPtr factory;
+  factory.Attach(FontFactory::GetInstance());
+  // File based
+  FontBuilderArray font_builder_array;
+  BuilderForFontFile(SAMPLE_TTF_FILE, factory, &font_builder_array);
+  FontBuilderPtr font_builder = font_builder_array[0];
+  // Memory based
+  FontBuilderArray font_builder_array2;
+  factory->LoadFontsForBuilding(&input_buffer, &font_builder_array2);
+  FontBuilderPtr font_builder2 = font_builder_array2[0];
+
+  for (size_t i = 0; i < SAMPLE_TTF_KNOWN_TAGS; ++i) {
+    EXPECT_TRUE(font_builder->HasTableBuilder(TTF_KNOWN_TAGS[i]));
+    EXPECT_TRUE(font_builder2->HasTableBuilder(TTF_KNOWN_TAGS[i]));
+  }
+
+  // Generic table
+  Ptr<GenericTableBuilder> gdef_builder =
+      down_cast<GenericTableBuilder*>(font_builder->GetTableBuilder(Tag::feat));
+  HeaderPtr gdef_header = gdef_builder->header();
+  EXPECT_EQ(gdef_header->length(), TTF_LENGTH[SAMPLE_TTF_FEAT]);
+  EXPECT_EQ(gdef_header->offset(), TTF_OFFSET[SAMPLE_TTF_FEAT]);
+  EXPECT_EQ(gdef_header->checksum(), TTF_CHECKSUM[SAMPLE_TTF_FEAT]);
+  EXPECT_TRUE(gdef_header->checksum_valid());
+
+  WritableFontDataPtr wfd;
+  wfd.Attach(gdef_builder->Data());
+  ByteVector b;
+  b.resize(TTF_LENGTH[SAMPLE_TTF_FEAT]);
+  wfd->ReadBytes(0, &(b[0]), 0, TTF_LENGTH[SAMPLE_TTF_FEAT]);
+  EXPECT_EQ(memcmp(&(b[0]), TTF_FEAT_DATA, TTF_LENGTH[SAMPLE_TTF_FEAT]), 0);
+
+  // Header table
+  FontHeaderTableBuilderPtr header_builder =
+      down_cast<FontHeaderTable::Builder*>(
+          font_builder->GetTableBuilder(Tag::head));
+  HeaderPtr header_header = header_builder->header();
+  EXPECT_EQ(header_header->length(), TTF_LENGTH[SAMPLE_TTF_HEAD]);
+  EXPECT_EQ(header_header->offset(), TTF_OFFSET[SAMPLE_TTF_HEAD]);
+  EXPECT_EQ(header_header->checksum(), TTF_CHECKSUM[SAMPLE_TTF_HEAD]);
+  EXPECT_TRUE(header_header->checksum_valid());
+
+  // Data conformance
+  for (size_t i = 0; i < SAMPLE_TTF_KNOWN_TAGS; ++i) {
+    ByteVector b1, b2;
+    b1.resize(TTF_LENGTH[i]);
+    b2.resize(TTF_LENGTH[i]);
+    TableBuilderPtr builder1 =
+        font_builder->GetTableBuilder(TTF_KNOWN_TAGS[i]);
+    TableBuilderPtr builder2 =
+        font_builder2->GetTableBuilder(TTF_KNOWN_TAGS[i]);
+    WritableFontDataPtr wfd1;
+    wfd1.Attach(builder1->Data());
+    WritableFontDataPtr wfd2;
+    wfd2.Attach(builder2->Data());
+    wfd1->ReadBytes(0, &(b1[0]), 0, TTF_LENGTH[i]);
+    wfd2->ReadBytes(0, &(b2[0]), 0, TTF_LENGTH[i]);
+    EXPECT_EQ(memcmp(&(b1[0]), &(b2[0]), TTF_LENGTH[i]), 0);
+  }
+
+  return true;
+}
+
+bool TestTTFReadWrite() {
+  FontFactoryPtr factory;
+  factory.Attach(FontFactory::GetInstance());
+  FontBuilderArray font_builder_array;
+  BuilderForFontFile(SAMPLE_TTF_FILE, factory, &font_builder_array);
+  FontBuilderPtr font_builder = font_builder_array[0];
+  FontPtr font;
+  font.Attach(font_builder->Build());
+  MemoryOutputStream output_stream;
+  factory->SerializeFont(font, &output_stream);
+  EXPECT_GE(output_stream.Size(), SAMPLE_TTF_SIZE);
+
+  return true;
+}
+
+bool TestTTFMemoryBasedReadWrite() {
+  ByteVector input_buffer;
+  LoadFile(SAMPLE_TTF_FILE, &input_buffer);
+
+  FontFactoryPtr factory;
+  factory.Attach(FontFactory::GetInstance());
+  FontBuilderArray font_builder_array;
+  factory->LoadFontsForBuilding(&input_buffer, &font_builder_array);
+  FontBuilderPtr font_builder = font_builder_array[0];
+  FontPtr font;
+  font.Attach(font_builder->Build());
+  MemoryOutputStream output_stream;
+  factory->SerializeFont(font, &output_stream);
+  EXPECT_GE(output_stream.Size(), input_buffer.size());
+
+  return true;
+}
+
+}  // namespace sfntly
+
+TEST(FontParsing, All) {
+  ASSERT_TRUE(sfntly::TestFontParsing());
+  ASSERT_TRUE(sfntly::TestTTFReadWrite());
+  ASSERT_TRUE(sfntly::TestTTFMemoryBasedReadWrite());
+}
diff --git a/test/hdmx_test.cc b/test/hdmx_test.cc
new file mode 100644
index 0000000..cdc4ed0
--- /dev/null
+++ b/test/hdmx_test.cc
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "gtest/gtest.h"
+#include "sfntly/font.h"
+#include "sfntly/table/core/horizontal_device_metrics_table.h"
+#include "test/test_data.h"
+#include "test/test_font_utils.h"
+
+namespace sfntly {
+
+const int32_t HDMX_VERSION = 0;
+const int32_t HDMX_NUM_RECORDS = 4;
+const int32_t HDMX_RECORD_SIZE = 628;
+const int32_t HDMX_PIXEL_SIZE[] = {10, 11, 12, 13};
+const int32_t HDMX_MAX_WIDTH[] = {5, 6, 7, 7};
+
+bool TestReadingHdmxTable() {
+  FontFactoryPtr factory;
+  factory.Attach(FontFactory::GetInstance());
+  FontArray font_array;
+  LoadFont(SAMPLE_BITMAP_FONT, factory, &font_array);
+  FontPtr font = font_array[0];
+
+  HorizontalDeviceMetricsTablePtr hdmx_table =
+      down_cast<HorizontalDeviceMetricsTable*>(font->GetTable(Tag::hdmx));
+
+  EXPECT_FALSE(hdmx_table == NULL);
+
+  EXPECT_EQ(hdmx_table->Version(), HDMX_VERSION);
+  EXPECT_EQ(hdmx_table->NumRecords(), HDMX_NUM_RECORDS);
+  EXPECT_EQ(hdmx_table->RecordSize(), HDMX_RECORD_SIZE);
+
+  for (int32_t i = 0; i < HDMX_NUM_RECORDS; ++i) {
+    EXPECT_EQ(hdmx_table->PixelSize(i), HDMX_PIXEL_SIZE[i]);
+    EXPECT_EQ(hdmx_table->MaxWidth(i), HDMX_MAX_WIDTH[i]);
+  }
+
+  EXPECT_EQ(hdmx_table->Width(0, 0), HDMX_MAX_WIDTH[0]);
+  EXPECT_EQ(hdmx_table->Width(0, 19), HDMX_MAX_WIDTH[0]);
+  EXPECT_EQ(hdmx_table->Width(0, 623), HDMX_MAX_WIDTH[0]);
+  EXPECT_EQ(hdmx_table->Width(1, 0), HDMX_MAX_WIDTH[1]);
+  EXPECT_EQ(hdmx_table->Width(1, 19), HDMX_MAX_WIDTH[1]);
+  EXPECT_EQ(hdmx_table->Width(1, 623), HDMX_MAX_WIDTH[1]);
+  EXPECT_EQ(hdmx_table->Width(2, 0), HDMX_MAX_WIDTH[2]);
+  EXPECT_EQ(hdmx_table->Width(2, 19), HDMX_MAX_WIDTH[2]);
+  EXPECT_EQ(hdmx_table->Width(2, 623), HDMX_MAX_WIDTH[2]);
+  EXPECT_EQ(hdmx_table->Width(3, 0), HDMX_MAX_WIDTH[3]);
+  EXPECT_EQ(hdmx_table->Width(3, 19), HDMX_MAX_WIDTH[3]);
+  EXPECT_EQ(hdmx_table->Width(3, 623), HDMX_MAX_WIDTH[3]);
+
+#if defined(SFNTLY_NO_EXCEPTION)
+  EXPECT_EQ(hdmx_table->PixelSize(4), -1);
+  EXPECT_EQ(hdmx_table->PixelSize(-1), -1);
+  EXPECT_EQ(hdmx_table->MaxWidth(4), -1);
+  EXPECT_EQ(hdmx_table->MaxWidth(-1), -1);
+  EXPECT_EQ(hdmx_table->Width(0, 624), -1);
+  EXPECT_EQ(hdmx_table->Width(1, -1), -1);
+  EXPECT_EQ(hdmx_table->Width(-1, 0), -1);
+  EXPECT_EQ(hdmx_table->Width(-1, -1), -1);
+#endif
+  return true;
+}
+
+}  // namespace sfntly
+
+TEST(HdmxTable, All) {
+  ASSERT_TRUE(sfntly::TestReadingHdmxTable());
+}
diff --git a/test/lock_test.cc b/test/lock_test.cc
new file mode 100644
index 0000000..b29a4bf
--- /dev/null
+++ b/test/lock_test.cc
@@ -0,0 +1,244 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include <stdlib.h>
+
+#include "gtest/gtest.h"
+#include "sfntly/port/lock.h"
+#include "test/platform_thread.h"
+
+namespace sfntly {
+
+// Basic test to make sure that Acquire()/Unlock()/Try() don't crash
+
+class BasicLockTestThread : public PlatformThread::Delegate {
+ public:
+  BasicLockTestThread(Lock* lock) : lock_(lock), acquired_(0) {}
+
+  virtual void ThreadMain() {
+    for (int i = 0; i < 10; i++) {
+      lock_->Acquire();
+      acquired_++;
+      lock_->Unlock();
+    }
+    for (int i = 0; i < 10; i++) {
+      lock_->Acquire();
+      acquired_++;
+      PlatformThread::Sleep(rand() % 20);
+      lock_->Unlock();
+    }
+    for (int i = 0; i < 10; i++) {
+      if (lock_->Try()) {
+        acquired_++;
+        PlatformThread::Sleep(rand() % 20);
+        lock_->Unlock();
+      }
+    }
+  }
+
+  int acquired() const { return acquired_; }
+
+ private:
+  Lock* lock_;
+  int acquired_;
+
+  NO_COPY_AND_ASSIGN(BasicLockTestThread);
+};
+
+bool BasicLockTest() {
+  Lock lock;
+  BasicLockTestThread thread(&lock);
+  PlatformThreadHandle handle = kNullThreadHandle;
+
+  EXPECT_TRUE(PlatformThread::Create(&thread, &handle));
+
+  int acquired = 0;
+  for (int i = 0; i < 5; i++) {
+    lock.Acquire();
+    acquired++;
+    lock.Unlock();
+  }
+  for (int i = 0; i < 10; i++) {
+    lock.Acquire();
+    acquired++;
+    PlatformThread::Sleep(rand() % 20);
+    lock.Unlock();
+  }
+  for (int i = 0; i < 10; i++) {
+    if (lock.Try()) {
+      acquired++;
+      PlatformThread::Sleep(rand() % 20);
+      lock.Unlock();
+    }
+  }
+  for (int i = 0; i < 5; i++) {
+    lock.Acquire();
+    acquired++;
+    PlatformThread::Sleep(rand() % 20);
+    lock.Unlock();
+  }
+
+  PlatformThread::Join(handle);
+
+  EXPECT_GE(acquired, 20);
+  EXPECT_GE(thread.acquired(), 20);
+
+  return true;
+}
+
+// Test that Try() works as expected -------------------------------------------
+
+class TryLockTestThread : public PlatformThread::Delegate {
+ public:
+  TryLockTestThread(Lock* lock) : lock_(lock), got_lock_(false) {}
+
+  virtual void ThreadMain() {
+    got_lock_ = lock_->Try();
+    if (got_lock_)
+      lock_->Unlock();
+  }
+
+  bool got_lock() const { return got_lock_; }
+
+ private:
+  Lock* lock_;
+  bool got_lock_;
+
+  NO_COPY_AND_ASSIGN(TryLockTestThread);
+};
+
+bool TryLockTest() {
+  Lock lock;
+
+  EXPECT_TRUE(lock.Try());
+  // We now have the lock....
+
+  // This thread will not be able to get the lock.
+  {
+    TryLockTestThread thread(&lock);
+    PlatformThreadHandle handle = kNullThreadHandle;
+
+    EXPECT_TRUE(PlatformThread::Create(&thread, &handle));
+
+    PlatformThread::Join(handle);
+
+    EXPECT_FALSE(thread.got_lock());
+  }
+
+  lock.Unlock();
+
+  // This thread will....
+  {
+    TryLockTestThread thread(&lock);
+    PlatformThreadHandle handle = kNullThreadHandle;
+
+    EXPECT_TRUE(PlatformThread::Create(&thread, &handle));
+
+    PlatformThread::Join(handle);
+
+    EXPECT_TRUE(thread.got_lock());
+    // But it released it....
+    EXPECT_TRUE(lock.Try());
+  }
+
+  lock.Unlock();
+  return true;
+}
+
+// Tests that locks actually exclude -------------------------------------------
+
+class MutexLockTestThread : public PlatformThread::Delegate {
+ public:
+  MutexLockTestThread(Lock* lock, int* value) : lock_(lock), value_(value) {}
+
+  // Static helper which can also be called from the main thread.
+  static void DoStuff(Lock* lock, int* value) {
+    for (int i = 0; i < 40; i++) {
+      lock->Acquire();
+      int v = *value;
+      PlatformThread::Sleep(rand() % 10);
+      *value = v + 1;
+      lock->Unlock();
+    }
+  }
+
+  virtual void ThreadMain() {
+    DoStuff(lock_, value_);
+  }
+
+ private:
+  Lock* lock_;
+  int* value_;
+
+  NO_COPY_AND_ASSIGN(MutexLockTestThread);
+};
+
+bool MutexTwoThreads() {
+  Lock lock;
+  int value = 0;
+
+  MutexLockTestThread thread(&lock, &value);
+  PlatformThreadHandle handle = kNullThreadHandle;
+
+  EXPECT_TRUE(PlatformThread::Create(&thread, &handle));
+
+  MutexLockTestThread::DoStuff(&lock, &value);
+
+  PlatformThread::Join(handle);
+
+  EXPECT_EQ(2 * 40, value);
+  return true;
+}
+
+bool MutexFourThreads() {
+  Lock lock;
+  int value = 0;
+
+  MutexLockTestThread thread1(&lock, &value);
+  MutexLockTestThread thread2(&lock, &value);
+  MutexLockTestThread thread3(&lock, &value);
+  PlatformThreadHandle handle1 = kNullThreadHandle;
+  PlatformThreadHandle handle2 = kNullThreadHandle;
+  PlatformThreadHandle handle3 = kNullThreadHandle;
+
+  EXPECT_TRUE(PlatformThread::Create(&thread1, &handle1));
+  EXPECT_TRUE(PlatformThread::Create(&thread2, &handle2));
+  EXPECT_TRUE(PlatformThread::Create(&thread3, &handle3));
+
+  MutexLockTestThread::DoStuff(&lock, &value);
+
+  PlatformThread::Join(handle1);
+  PlatformThread::Join(handle2);
+  PlatformThread::Join(handle3);
+
+  EXPECT_EQ(4 * 40, value);
+  return true;
+}
+
+}  // namespace sfntly
+
+TEST(LockTest, Basic) {
+  ASSERT_TRUE(sfntly::BasicLockTest());
+}
+
+TEST(LockTest, TryLock) {
+  ASSERT_TRUE(sfntly::TryLockTest());
+}
+
+TEST(LockTest, Mutex) {
+  ASSERT_TRUE(sfntly::MutexTwoThreads());
+  ASSERT_TRUE(sfntly::MutexFourThreads());
+}
diff --git a/test/memory_io_test.cc b/test/memory_io_test.cc
new file mode 100755
index 0000000..b34e1e7
--- /dev/null
+++ b/test/memory_io_test.cc
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+
+#include <algorithm>
+
+#include "gtest/gtest.h"
+#include "sfntly/port/memory_input_stream.h"
+#include "sfntly/port/memory_output_stream.h"
+#include "sfntly/port/type.h"
+
+namespace {
+  const char* kTestData =
+"01234567890123456789012345678901234567890123456789"  // 50
+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwx"  // 100
+"yz";                                                 // 102
+  const size_t kTestBufferLen = 102;
+}
+
+namespace sfntly {
+
+bool TestMemoryInputStream() {
+  ByteVector test_buffer;
+  test_buffer.resize(kTestBufferLen);
+  std::copy(kTestData, kTestData + kTestBufferLen, test_buffer.begin());
+
+  MemoryInputStream is;
+  is.Attach(&(test_buffer[0]), kTestBufferLen);
+  EXPECT_EQ(is.Available(), (int32_t)kTestBufferLen);
+
+  // Read one byte
+  EXPECT_EQ(is.Read(), '0');  // position 1
+  EXPECT_EQ(is.Read(), '1');  // position 2
+  EXPECT_EQ(is.Read(), '2');  // position 3
+
+  // Read byte vector
+  ByteVector b;
+  b.resize(7);
+  EXPECT_EQ(is.Read(&b), 7);  // position 10
+  EXPECT_EQ(memcmp(&(b[0]), &(test_buffer[0]) + 3, 7), 0);
+
+  b.resize(17);
+  EXPECT_EQ(is.Read(&b, 7, 10), 10);  // position 20
+  EXPECT_EQ(memcmp(&(b[0]), &(test_buffer[0]) + 3, 17), 0);
+
+  // Test skip
+  b.clear();
+  b.resize(10);
+  EXPECT_EQ(is.Skip(30), 30);  // position 50
+  EXPECT_EQ(is.Read(&b), 10);  // position 60
+  EXPECT_EQ(memcmp(&(b[0]), &(test_buffer[0]) + 50, 10), 0);
+  b.clear();
+  b.resize(10);
+  EXPECT_EQ(is.Skip(-20), -20);  // position 40
+  EXPECT_EQ(is.Read(&b), 10);  // position 50
+  EXPECT_EQ(memcmp(&(b[0]), &(test_buffer[0]) + 40, 10), 0);
+
+  EXPECT_EQ(is.Available(), (int32_t)kTestBufferLen - 50);
+  EXPECT_EQ(is.Skip(-60), -50);  // Out of bound, position 0
+  EXPECT_EQ(is.Skip(kTestBufferLen + 10), (int32_t)kTestBufferLen);
+
+  b.clear();
+  b.resize(10);
+  is.Unread(&b);
+  EXPECT_EQ(memcmp(&(b[0]), &(test_buffer[0]) + kTestBufferLen - 10, 10), 0);
+
+  return true;
+}
+
+bool TestMemoryOutputStream() {
+  ByteVector test_buffer;
+  test_buffer.resize(kTestBufferLen);
+  std::copy(kTestData, kTestData + kTestBufferLen, test_buffer.begin());
+
+  MemoryOutputStream os;
+  os.Write(&(test_buffer[0]), (int32_t)50, (int32_t)(kTestBufferLen - 50));
+  EXPECT_EQ(os.Size(), kTestBufferLen - 50);
+  EXPECT_EQ(memcmp(os.Get(), &(test_buffer[0]) + 50, kTestBufferLen - 50), 0);
+
+  return true;
+}
+
+}  // namespace sfntly
+
+TEST(MemoryIO, All) {
+  ASSERT_TRUE(sfntly::TestMemoryInputStream());
+  ASSERT_TRUE(sfntly::TestMemoryOutputStream());
+}
diff --git a/test/name_editing_test.cc b/test/name_editing_test.cc
new file mode 100644
index 0000000..260d9d4
--- /dev/null
+++ b/test/name_editing_test.cc
@@ -0,0 +1,242 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+// Must include this before ICU to avoid stdint redefinition issue.
+#include "sfntly/port/type.h"
+
+#include <unicode/ustring.h>
+#include <unicode/unistr.h>
+
+#include "gtest/gtest.h"
+#include "sfntly/data/memory_byte_array.h"
+#include "sfntly/font.h"
+#include "sfntly/font_factory.h"
+#include "sfntly/port/memory_input_stream.h"
+#include "sfntly/port/memory_output_stream.h"
+#include "sfntly/table/core/name_table.h"
+#include "sfntly/tag.h"
+#include "test/test_data.h"
+#include "test/test_font_utils.h"
+
+namespace sfntly {
+
+static ByteVector input_buffer;
+
+void LoadTestFile(FontFactory* factory, FontBuilderArray* font_builders) {
+  assert(factory);
+  assert(font_builders);
+  if (input_buffer.empty()) {
+    LoadFile(SAMPLE_TTF_FILE, &input_buffer);
+  }
+  factory->LoadFontsForBuilding(&input_buffer, font_builders);
+}
+
+bool TestChangeOneName() {
+  FontFactoryPtr factory;
+  factory.Attach(FontFactory::GetInstance());
+  FontBuilderArray font_builder_array;
+  LoadTestFile(factory, &font_builder_array);
+  FontBuilderPtr font_builder = font_builder_array[0];
+
+  NameTableBuilderPtr name_builder = down_cast<NameTable::Builder*>(
+      font_builder->GetTableBuilder(Tag::name));
+
+  // Change the font name.
+  NameEntryBuilderPtr neb =
+      name_builder->NameBuilder(PlatformId::kWindows,
+                                WindowsEncodingId::kUnicodeUCS2,
+                                WindowsLanguageId::kEnglish_UnitedStates,
+                                NameId::kFontFamilyName);
+  U_STRING_DECL(new_name, "Timothy", 7);
+  neb->SetName(new_name);
+
+  // Build the font.
+  FontPtr font;
+  font.Attach(font_builder->Build());
+
+  // Serialize and reload the serialized font.
+  MemoryOutputStream os;
+  factory->SerializeFont(font, &os);
+  MemoryInputStream is;
+  is.Attach(os.Get(), os.Size());
+  FontArray font_array;
+  factory->LoadFonts(&is, &font_array);
+  FontPtr new_font = font_array[0];
+
+  // Check the font name.
+  NameTablePtr name_table = down_cast<NameTable*>(font->GetTable(Tag::name));
+  UChar* name = name_table->Name(PlatformId::kWindows,
+                                 WindowsEncodingId::kUnicodeUCS2,
+                                 WindowsLanguageId::kEnglish_UnitedStates,
+                                 NameId::kFontFamilyName);
+  EXPECT_TRUE(name != NULL);
+  EXPECT_EQ(u_strcmp(name, new_name), 0);
+  delete[] name;
+  return true;
+}
+
+bool TestModifyNameTableAndRevert() {
+  FontFactoryPtr factory;
+  factory.Attach(FontFactory::GetInstance());
+  FontBuilderArray font_builder_array;
+  LoadTestFile(factory, &font_builder_array);
+  FontBuilderPtr font_builder = font_builder_array[0];
+
+  NameTableBuilderPtr name_builder = down_cast<NameTable::Builder*>(
+      font_builder->GetTableBuilder(Tag::name));
+
+  // Change the font name.
+  NameEntryBuilderPtr neb =
+      name_builder->NameBuilder(PlatformId::kWindows,
+                                WindowsEncodingId::kUnicodeUCS2,
+                                WindowsLanguageId::kEnglish_UnitedStates,
+                                NameId::kFontFamilyName);
+  NameTable::NameEntry* neb_entry = neb->name_entry();
+  UChar* original_name = neb_entry->Name();
+  EXPECT_TRUE(original_name != NULL);
+
+  U_STRING_DECL(new_name, "Timothy", 7);
+  neb->SetName(new_name);
+  name_builder->RevertNames();
+
+  // Build the font.
+  FontPtr font;
+  font.Attach(font_builder->Build());
+
+  // Serialize and reload the serialized font.
+  MemoryOutputStream os;
+  factory->SerializeFont(font, &os);
+  MemoryInputStream is;
+  is.Attach(os.Get(), os.Size());
+  FontArray font_array;
+  factory->LoadFonts(&is, &font_array);
+  FontPtr new_font = font_array[0];
+
+  // Check the font name.
+  NameTablePtr name_table = down_cast<NameTable*>(font->GetTable(Tag::name));
+  UChar* name = name_table->Name(PlatformId::kWindows,
+                                 WindowsEncodingId::kUnicodeUCS2,
+                                 WindowsLanguageId::kEnglish_UnitedStates,
+                                 NameId::kFontFamilyName);
+
+  EXPECT_EQ(u_strcmp(name, original_name), 0);
+  delete[] name;
+  delete[] original_name;
+
+  return true;
+}
+
+bool TestRemoveOneName() {
+  FontFactoryPtr factory;
+  factory.Attach(FontFactory::GetInstance());
+  FontBuilderArray font_builder_array;
+  LoadTestFile(factory, &font_builder_array);
+  FontBuilderPtr font_builder = font_builder_array[0];
+
+  NameTableBuilderPtr name_builder = down_cast<NameTable::Builder*>(
+      font_builder->GetTableBuilder(Tag::name));
+
+  EXPECT_TRUE(name_builder->Has(PlatformId::kWindows,
+                                WindowsEncodingId::kUnicodeUCS2,
+                                WindowsLanguageId::kEnglish_UnitedStates,
+                                NameId::kFontFamilyName));
+  EXPECT_TRUE(name_builder->Remove(PlatformId::kWindows,
+                                   WindowsEncodingId::kUnicodeUCS2,
+                                   WindowsLanguageId::kEnglish_UnitedStates,
+                                   NameId::kFontFamilyName));
+
+  // Build the font.
+  FontPtr font;
+  font.Attach(font_builder->Build());
+
+  // Serialize and reload the serialized font.
+  MemoryOutputStream os;
+  factory->SerializeFont(font, &os);
+  MemoryInputStream is;
+  is.Attach(os.Get(), os.Size());
+  FontArray font_array;
+  factory->LoadFonts(&is, &font_array);
+  FontPtr new_font = font_array[0];
+
+  // Check the font name.
+  NameTablePtr name_table = down_cast<NameTable*>(font->GetTable(Tag::name));
+  UChar* name = name_table->Name(PlatformId::kWindows,
+                                 WindowsEncodingId::kUnicodeUCS2,
+                                 WindowsLanguageId::kEnglish_UnitedStates,
+                                 NameId::kFontFamilyName);
+  EXPECT_TRUE(name == NULL);
+
+  return true;
+}
+
+// Note: Function is not implemented but the test case is built.  Uncomment
+//       when NameTable::clear() is implemented.
+/*
+bool TestClearAllNamesAndSetOne() {
+  FontFactoryPtr factory;
+  factory.Attach(FontFactory::GetInstance());
+  FontBuilderArray font_builder_array;
+  LoadTestFile(factory, &font_builder_array);
+  FontBuilderPtr font_builder = font_builder_array[0];
+
+  NameTableBuilderPtr name_builder = down_cast<NameTable::Builder*>(
+      font_builder->GetTableBuilder(Tag::name));
+
+  EXPECT_GT(name_builder->builderCount(), 0);
+  name_builder->clear();
+  EXPECT_EQ(name_builder->builderCount(), 0);
+
+  // Change the font name.
+  NameEntryBuilderPtr neb =
+      name_builder->NameBuilder(PlatformId::kWindows,
+                                WindowsEncodingId::kUnicodeUCS2,
+                                WindowsLanguageId::kEnglish_UnitedStates,
+                                NameId::kFontFamilyName);
+  U_STRING_DECL(new_name, "Fred", 4);
+  neb->SetName(new_name);
+
+  // Build the font.
+  FontPtr font = font_builder->Build();
+
+  // Serialize and reload the serialized font.
+  MemoryOutputStream os;
+  factory->SerializeFont(font, &os);
+  FontArray font_array;
+  ByteArrayPtr new_ba = new MemoryByteArray(os.Get(), os.Size());
+  factory->LoadFonts(new_ba, &font_array);
+  FontPtr new_font = font_array[0];
+
+  // Check the font name.
+  NameTablePtr name_table = down_cast<NameTable*>(font->table(Tag::name));
+  UChar* name = name_table->Name(PlatformId::kWindows,
+                                 WindowsEncodingId::kUnicodeUCS2,
+                                 WindowsLanguageId::kEnglish_UnitedStates,
+                                 NameId::kFontFamilyName);
+  EXPECT_EQ(name_table->NameCount(), 1);
+  EXPECT_EQ(u_strcmp(name, new_name), 0);
+
+  delete[] name;
+  return true;
+}
+*/
+
+}  // namespace sfntly
+
+TEST(NameEditing, All) {
+  EXPECT_TRUE(sfntly::TestChangeOneName());
+  EXPECT_TRUE(sfntly::TestModifyNameTableAndRevert());
+  EXPECT_TRUE(sfntly::TestRemoveOneName());
+}
diff --git a/test/open_type_data_test.cc b/test/open_type_data_test.cc
new file mode 100644
index 0000000..0917aab
--- /dev/null
+++ b/test/open_type_data_test.cc
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "gtest/gtest.h"
+#include "sfntly/data/writable_font_data.h"
+#include "sfntly/data/memory_byte_array.h"
+
+namespace sfntly {
+
+const byte_t TEST_OTF_DATA[] =
+    {0xff, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01};
+
+bool TestOTFRead() {
+  ByteVector bytes;
+  for (size_t i = 0; i < sizeof(TEST_OTF_DATA) / sizeof(byte_t); ++i) {
+    bytes.push_back(TEST_OTF_DATA[i]);
+  }
+  ByteArrayPtr array = new MemoryByteArray(&(bytes[0]), bytes.size());
+  ReadableFontDataPtr data = new ReadableFontData(array);
+
+  EXPECT_EQ(-1, data->ReadByte(0));
+  EXPECT_EQ(0xff, data->ReadUByte(0));
+  EXPECT_EQ(0x01, data->ReadByte(1));
+  EXPECT_EQ(65281, data->ReadUShort(0));
+  EXPECT_EQ(-255, data->ReadShort(0));
+  EXPECT_EQ(16711937, data->ReadUInt24(0));
+  EXPECT_EQ(4278255873LL, data->ReadULong(0));
+  EXPECT_EQ(-16711423, data->ReadLong(0));
+  return true;
+}
+
+bool TestOTFCopy() {
+  ByteVector source_bytes(1024);
+  for (size_t i = 0; i < source_bytes.size(); ++i) {
+    source_bytes[i] = (byte_t)(i & 0xff);
+  }
+  ByteArrayPtr source_array = new MemoryByteArray(&(source_bytes[0]), 1024);
+  ReadableFontDataPtr source = new ReadableFontData(source_array);
+
+  ByteVector destination_bytes(1024);
+  ByteArrayPtr destination_array =
+      new MemoryByteArray(&(destination_bytes[0]), 1024);
+  WritableFontDataPtr destination = new WritableFontData(destination_array);
+
+  int32_t length = source->CopyTo(destination);
+  EXPECT_EQ(1024, length);
+  EXPECT_TRUE(std::equal(source_bytes.begin(), source_bytes.end(),
+                         destination_bytes.begin()));
+  return true;
+}
+
+}  // namespace sfntly
+
+TEST(OpenTypeData, All) {
+  ASSERT_TRUE(sfntly::TestOTFRead());
+  ASSERT_TRUE(sfntly::TestOTFCopy());
+}
diff --git a/test/otf_basic_editing_test.cc b/test/otf_basic_editing_test.cc
new file mode 100644
index 0000000..7388fac
--- /dev/null
+++ b/test/otf_basic_editing_test.cc
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "gtest/gtest.h"
+#include "sfntly/font.h"
+#include "sfntly/font_factory.h"
+#include "sfntly/table/core/font_header_table.h"
+#include "sfntly/tag.h"
+#include "sfntly/data/memory_byte_array.h"
+#include "sfntly/port/endian.h"
+#include "sfntly/port/file_input_stream.h"
+#include "sfntly/port/memory_output_stream.h"
+#include "test/test_data.h"
+#include "test/test_font_utils.h"
+
+namespace sfntly {
+
+bool TestOTFBasicEditing() {
+  FontFactoryPtr factory;
+  factory.Attach(FontFactory::GetInstance());
+  FontBuilderArray font_builder_array;
+  BuilderForFontFile(SAMPLE_TTF_FILE, factory, &font_builder_array);
+  FontBuilderPtr font_builder = font_builder_array[0];
+
+  // ensure the builder is not bogus
+  EXPECT_TRUE(font_builder != NULL);
+  TableBuilderMap* builder_map = font_builder->table_builders();
+  EXPECT_TRUE(builder_map != NULL);
+  IntegerSet builder_tags;
+  for (TableBuilderMap::iterator i = builder_map->begin(),
+                                 e = builder_map->end(); i != e; ++i) {
+    EXPECT_TRUE(i->second != NULL);
+    if (i->second == NULL) {
+      char tag[5] = {0};
+      int32_t value = ToBE32(i->first);
+      memcpy(tag, &value, 4);
+      fprintf(stderr, "tag %s does not have valid builder\n", tag);
+    } else {
+      builder_tags.insert(i->first);
+    }
+  }
+
+  FontHeaderTableBuilderPtr header_builder =
+      down_cast<FontHeaderTable::Builder*>(
+          font_builder->GetTableBuilder(Tag::head));
+  int64_t mod_date = header_builder->Modified();
+  header_builder->SetModified(mod_date + 1);
+  FontPtr font;
+  font.Attach(font_builder->Build());
+
+  // ensure every table had a builder
+  const TableMap* table_map = font->GetTableMap();
+  for (TableMap::const_iterator i = table_map->begin(), e = table_map->end();
+                                i != e; ++i) {
+    TablePtr table = (*i).second;
+    HeaderPtr header = table->header();
+    EXPECT_TRUE(builder_tags.find(header->tag()) != builder_tags.end());
+    builder_tags.erase(header->tag());
+  }
+  EXPECT_TRUE(builder_tags.empty());
+
+  FontHeaderTablePtr header =
+      down_cast<FontHeaderTable*>(font->GetTable(Tag::head));
+  int64_t after_mod_date = header->Modified();
+  EXPECT_EQ(mod_date + 1, after_mod_date);
+
+  // Checksum correctness of builder.
+  TablePtr post = font->GetTable(Tag::post);
+  EXPECT_EQ(post->CalculatedChecksum(), TTF_CHECKSUM[SAMPLE_TTF_POST]);
+  return true;
+}
+
+}  // namespace sfntly
+
+TEST(OTFBasicEditing, All) {
+  ASSERT_TRUE(sfntly::TestOTFBasicEditing());
+}
diff --git a/test/platform_thread.cc b/test/platform_thread.cc
new file mode 100644
index 0000000..6a0b84b
--- /dev/null
+++ b/test/platform_thread.cc
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "test/platform_thread.h"
+
+namespace sfntly {
+
+#if defined (WIN32)
+
+DWORD __stdcall ThreadFunc(void* params) {
+  PlatformThread::Delegate* delegate =
+      static_cast<PlatformThread::Delegate*>(params);
+  delegate->ThreadMain();
+  return 0;
+}
+
+// static
+bool PlatformThread::Create(Delegate* delegate,
+                            PlatformThreadHandle* thread_handle) {
+  assert(thread_handle);
+  *thread_handle = CreateThread(NULL, 0, ThreadFunc, delegate, 0, NULL);
+  if (!(*thread_handle)) {
+    return false;
+  }
+
+  return true;
+}
+
+// static
+void PlatformThread::Join(PlatformThreadHandle thread_handle) {
+  assert(thread_handle);
+  DWORD result = WaitForSingleObject(thread_handle, INFINITE);
+  assert(result == WAIT_OBJECT_0);
+  CloseHandle(thread_handle);
+}
+
+// static
+void PlatformThread::Sleep(int32_t duration_ms) {
+  ::Sleep(duration_ms);
+}
+
+#else
+
+void* ThreadFunc(void* params) {
+  PlatformThread::Delegate* delegate =
+      static_cast<PlatformThread::Delegate*>(params);
+  delegate->ThreadMain();
+  return NULL;
+}
+
+// static
+bool PlatformThread::Create(Delegate* delegate,
+                            PlatformThreadHandle* thread_handle) {
+  assert(thread_handle);
+
+  bool success = false;
+  pthread_attr_t attributes;
+  pthread_attr_init(&attributes);
+  success = !pthread_create(thread_handle, &attributes, ThreadFunc, delegate);
+  pthread_attr_destroy(&attributes);
+
+  return success;
+}
+
+// static
+void PlatformThread::Join(PlatformThreadHandle thread_handle) {
+  assert(thread_handle);
+  pthread_join(thread_handle, NULL);
+}
+
+// static
+void PlatformThread::Sleep(int32_t duration_ms) {
+  struct timespec sleep_time, remaining;
+
+  // Contains the portion of duration_ms >= 1 sec.
+  sleep_time.tv_sec = duration_ms / 1000;
+  duration_ms -= sleep_time.tv_sec * 1000;
+
+  // Contains the portion of duration_ms < 1 sec.
+  sleep_time.tv_nsec = duration_ms * 1000 * 1000;  // nanoseconds.
+
+  while (nanosleep(&sleep_time, &remaining) == -1 && errno == EINTR)
+    sleep_time = remaining;
+}
+
+#endif  // WIN32
+
+}  // namespace sfntly
diff --git a/test/platform_thread.h b/test/platform_thread.h
new file mode 100644
index 0000000..f236f4c
--- /dev/null
+++ b/test/platform_thread.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+// Simple platform thread implementation used to test our cross-platform locks.
+// This is a trimmed down version of Chromium base/threading/platform_thread.h.
+
+#ifndef SFNTLY_CPP_SRC_TEST_PLATFORM_THREAD_H_
+#define SFNTLY_CPP_SRC_TEST_PLATFORM_THREAD_H_
+
+#if defined (WIN32)
+#include <windows.h>
+#else  // Assume pthread
+#include <errno.h>
+#include <pthread.h>
+#include <time.h>
+#endif // if defined (WIN32)
+
+#include "sfntly/port/type.h"
+
+namespace sfntly {
+
+#if defined (WIN32)
+typedef HANDLE PlatformThreadHandle;
+const PlatformThreadHandle kNullThreadHandle = NULL;
+#else  // Assume pthread
+typedef pthread_t PlatformThreadHandle;
+const PlatformThreadHandle kNullThreadHandle = 0;
+#endif
+
+class PlatformThread {
+ public:
+  class Delegate {
+   public:
+     virtual ~Delegate() {}
+     virtual void ThreadMain() = 0;
+  };
+
+  // Sleeps for the specified duration (units are milliseconds).
+  static void Sleep(int32_t duration_ms);
+
+  // Creates a new thread using default stack size.  Upon success,
+  // |*thread_handle| will be assigned a handle to the newly created thread,
+  // and |delegate|'s ThreadMain method will be executed on the newly created
+  // thread.
+  // NOTE: When you are done with the thread handle, you must call Join to
+  // release system resources associated with the thread.  You must ensure that
+  // the Delegate object outlives the thread.
+  static bool Create(Delegate* delegate, PlatformThreadHandle* thread_handle);
+
+  // Joins with a thread created via the Create function.  This function blocks
+  // the caller until the designated thread exits.  This will invalidate
+  // |thread_handle|.
+  static void Join(PlatformThreadHandle thread_handle);
+
+private:
+  PlatformThread() {}
+  NO_COPY_AND_ASSIGN(PlatformThread);
+};
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_TEST_PLATFORM_THREAD_H_
diff --git a/test/serialization_test.cc b/test/serialization_test.cc
new file mode 100755
index 0000000..0f2f489
--- /dev/null
+++ b/test/serialization_test.cc
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "gtest/gtest.h"
+#include "sfntly/font.h"
+#include "sfntly/font_factory.h"
+#include "sfntly/port/memory_input_stream.h"
+#include "sfntly/port/memory_output_stream.h"
+#include "test/test_data.h"
+#include "test/test_font_utils.h"
+#include "test/serialization_test.h"
+
+namespace sfntly {
+
+bool TestSerialization() {
+  FontFactoryPtr factory1, factory2, factory3;
+  factory1.Attach(FontFactory::GetInstance());
+  FontArray font_array;
+  LoadFont(SAMPLE_TTF_FILE, factory1, &font_array);
+  FontPtr original = font_array[0];
+
+  factory2.Attach(FontFactory::GetInstance());
+  FontBuilderArray font_builder_array;
+  BuilderForFontFile(SAMPLE_TTF_FILE, factory2, &font_builder_array);
+  FontBuilderPtr font_builder = font_builder_array[0];
+
+  FontPtr intermediate;
+  intermediate.Attach(font_builder->Build());
+  MemoryOutputStream os;
+  factory2->SerializeFont(intermediate, &os);
+
+  factory3.Attach(FontFactory::GetInstance());
+  FontArray new_font_array;
+  MemoryInputStream is;
+  is.Attach(os.Get(), os.Size());
+  factory3->LoadFonts(&is, &new_font_array);
+  FontPtr serialized = new_font_array[0];
+
+  // Check number of tables
+  EXPECT_EQ(original->num_tables(), serialized->num_tables());
+
+  // Check if same set of tables
+  const TableMap* original_tables = original->GetTableMap();
+  const TableMap* serialized_tables = serialized->GetTableMap();
+  EXPECT_EQ(original_tables->size(), serialized_tables->size());
+  TableMap::const_iterator not_found = serialized_tables->end();
+  for (TableMap::const_iterator b = original_tables->begin(),
+                                e = original_tables->end(); b != e; ++b) {
+    EXPECT_TRUE((serialized_tables->find(b->first) != not_found));
+  }
+
+  // TODO(arthurhsu): check cmap equivalence
+  // Check checksum equivalence
+  for (size_t i = 0; i < SAMPLE_TTF_KNOWN_TAGS; ++i) {
+      TablePtr original_table = original->GetTable(TTF_KNOWN_TAGS[i]);
+      TablePtr serialized_table = serialized->GetTable(TTF_KNOWN_TAGS[i]);
+    EXPECT_EQ(original_table->CalculatedChecksum(),
+              serialized_table->CalculatedChecksum());
+    EXPECT_EQ(original_table->DataLength(), serialized_table->DataLength());
+
+    if (TTF_KNOWN_TAGS[i] == Tag::hhea) {
+      EXPECT_TRUE(VerifyHHEA(original_table, serialized_table));
+    } else if (TTF_KNOWN_TAGS[i] == Tag::glyf) {
+        EXPECT_TRUE(VerifyGLYF(original_table, serialized_table));
+    } else if (TTF_KNOWN_TAGS[i] == Tag::hmtx) {
+        EXPECT_TRUE(VerifyHMTX(original_table, serialized_table));
+    } else if (TTF_KNOWN_TAGS[i] == Tag::loca) {
+        EXPECT_TRUE(VerifyLOCA(original_table, serialized_table));
+    } else if (TTF_KNOWN_TAGS[i] == Tag::maxp) {
+        EXPECT_TRUE(VerifyMAXP(original_table, serialized_table));
+    } else if (TTF_KNOWN_TAGS[i] == Tag::name) {
+        EXPECT_TRUE(VerifyNAME(original_table, serialized_table));
+    } else if (TTF_KNOWN_TAGS[i] == Tag::OS_2) {
+        EXPECT_TRUE(VerifyOS_2(original_table, serialized_table));
+    }
+  }
+
+  return true;
+}
+
+bool TestSerializationBitmap() {
+  FontFactoryPtr factory1, factory2, factory3;
+  factory1.Attach(FontFactory::GetInstance());
+  FontArray font_array;
+  LoadFont(SAMPLE_BITMAP_FONT, factory1, &font_array);
+  FontPtr original = font_array[0];
+
+  factory2.Attach(FontFactory::GetInstance());
+  FontBuilderArray font_builder_array;
+  BuilderForFontFile(SAMPLE_BITMAP_FONT, factory2, &font_builder_array);
+  FontBuilderPtr font_builder = font_builder_array[0];
+
+  FontPtr intermediate;
+  intermediate.Attach(font_builder->Build());
+  MemoryOutputStream os;
+  factory2->SerializeFont(intermediate, &os);
+
+  factory3.Attach(FontFactory::GetInstance());
+  FontArray new_font_array;
+  MemoryInputStream is;
+  is.Attach(os.Get(), os.Size());
+  factory3->LoadFonts(&is, &new_font_array);
+  FontPtr serialized = new_font_array[0];
+
+  // Check number of tables
+  EXPECT_EQ(original->num_tables(), serialized->num_tables());
+
+  // Check if same set of tables
+  const TableMap* original_tables = original->GetTableMap();
+  const TableMap* serialized_tables = serialized->GetTableMap();
+  EXPECT_EQ(original_tables->size(), serialized_tables->size());
+  TableMap::const_iterator not_found = serialized_tables->end();
+  for (TableMap::const_iterator b = original_tables->begin(),
+                                e = original_tables->end(); b != e; ++b) {
+    EXPECT_TRUE((serialized_tables->find(b->first) != not_found));
+  }
+
+  // Check checksum equivalence
+  for (size_t i = 0; i < SAMPLE_BITMAP_KNOWN_TAGS; ++i) {
+      TablePtr original_table = original->GetTable(BITMAP_KNOWN_TAGS[i]);
+      TablePtr serialized_table = serialized->GetTable(BITMAP_KNOWN_TAGS[i]);
+    EXPECT_EQ(original_table->CalculatedChecksum(),
+              serialized_table->CalculatedChecksum());
+    EXPECT_EQ(original_table->DataLength(), serialized_table->DataLength());
+  }
+
+  return true;
+}
+
+}  // namespace sfntly
+
+TEST(Serialization, Simple) {
+  ASSERT_TRUE(sfntly::TestSerialization());
+}
+
+TEST(Serialization, Bitmap) {
+  ASSERT_TRUE(sfntly::TestSerializationBitmap());
+}
diff --git a/test/serialization_test.h b/test/serialization_test.h
new file mode 100644
index 0000000..8996793
--- /dev/null
+++ b/test/serialization_test.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_TEST_SERIALIZATION_TEST_H_
+#define SFNTLY_CPP_SRC_TEST_SERIALIZATION_TEST_H_
+
+#include "sfntly/table/table.h"
+
+namespace sfntly {
+
+bool VerifyHHEA(Table* original, Table* target);
+bool VerifyGLYF(Table* original, Table* target);
+bool VerifyHMTX(Table* original, Table* target);
+bool VerifyLOCA(Table* original, Table* target);
+bool VerifyMAXP(Table* original, Table* target);
+bool VerifyNAME(Table* original, Table* target);
+bool VerifyOS_2(Table* original, Table* target);
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_TEST_SERIALIZATION_TEST_H_
diff --git a/test/smart_pointer_test.cc b/test/smart_pointer_test.cc
new file mode 100644
index 0000000..9e81baa
--- /dev/null
+++ b/test/smart_pointer_test.cc
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "gtest/gtest.h"
+#define ENABLE_OBJECT_COUNTER
+#include "sfntly/port/refcount.h"
+
+using sfntly::RefCounted;
+using sfntly::Ptr;
+
+class Foo : public RefCounted<Foo> {
+public:  // put in something to make sure it's not empty
+  int foo_;
+  int foo() { return foo_; }
+};
+
+bool TestSmartPointer() {
+  // scope out allocation
+  {
+    Ptr<Foo> p1;
+    p1 = new Foo();
+    EXPECT_EQ(size_t(1), p1->ref_count_);
+    EXPECT_EQ(size_t(1), RefCounted<Foo>::object_counter_);
+
+    Ptr<Foo> p2;
+    p2 = p1;
+    EXPECT_EQ(size_t(2), p1->ref_count_);
+    EXPECT_EQ(size_t(2), p2->ref_count_);
+    EXPECT_EQ(size_t(1), RefCounted<Foo>::object_counter_);
+
+    Ptr<Foo> p3;
+    p3 = p1;
+    EXPECT_EQ(size_t(3), p1->ref_count_);
+    EXPECT_EQ(size_t(3), p2->ref_count_);
+    EXPECT_EQ(size_t(3), p3->ref_count_);
+    EXPECT_EQ(size_t(1), RefCounted<Foo>::object_counter_);
+
+    p2 = new Foo();
+    EXPECT_EQ(size_t(2), p1->ref_count_);
+    EXPECT_EQ(size_t(1), p2->ref_count_);
+    EXPECT_EQ(size_t(2), p3->ref_count_);
+    EXPECT_EQ(size_t(2), RefCounted<Foo>::object_counter_);
+
+    p3.Release();
+    EXPECT_EQ(size_t(1), p1->ref_count_);
+    EXPECT_EQ(NULL, p3.p_);
+    EXPECT_EQ(size_t(2), RefCounted<Foo>::object_counter_);
+
+    p2 = NULL;
+    EXPECT_EQ(size_t(1), RefCounted<Foo>::object_counter_);
+
+    p1 = p1;
+    EXPECT_EQ(size_t(1), p1->ref_count_);
+    EXPECT_EQ(size_t(1), RefCounted<Foo>::object_counter_);
+
+    p1 = &(*p1);
+    EXPECT_EQ(size_t(1), p1->ref_count_);
+    EXPECT_EQ(size_t(1), RefCounted<Foo>::object_counter_);
+  }
+  EXPECT_EQ(size_t(0), RefCounted<Foo>::object_counter_);
+  return true;
+}
+
+TEST(SmartPointer, All) {
+  ASSERT_TRUE(TestSmartPointer());
+}
diff --git a/test/test_data.cc b/test/test_data.cc
new file mode 100644
index 0000000..05bc759
--- /dev/null
+++ b/test/test_data.cc
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/tag.cc"
+#include "test/test_data.h"
+
+namespace sfntly {
+
+// If the TTF file used in test changed, the verify*.cc in test need to be
+// changed also.
+// TODO(arthurhsu): Refactor this into a test class and have all const inside.
+//                  This way we can test multiple fonts using same set of
+//                  code.
+
+const char* SAMPLE_TTF_FILE = "Tuffy.ttf";
+const char* SAMPLE_BITMAP_FONT = "AnonymousPro-Regular.ttf";
+
+const size_t SAMPLE_TTF_SIZE = 183936;
+const size_t SAMPLE_TTF_TABLES = 17;
+const size_t SAMPLE_TTF_KNOWN_TAGS = 16;
+const size_t SAMPLE_BITMAP_KNOWN_TAGS = 20;
+const size_t SAMPLE_TTF_FEAT = 3;
+const size_t SAMPLE_TTF_HEAD = 6;
+const size_t SAMPLE_TTF_POST = 14;
+
+const int32_t TTF_KNOWN_TAGS[] = {
+    Tag::OS_2, Tag::cmap, Tag::cvt,  Tag::feat, Tag::gasp,
+    Tag::glyf, Tag::head, Tag::hhea, Tag::hmtx, Tag::kern,
+    Tag::loca, Tag::maxp, Tag::morx, Tag::name, Tag::post,
+    Tag::prop };
+
+const int32_t BITMAP_KNOWN_TAGS[] = {
+    Tag::EBDT, Tag::EBLC, Tag::EBSC, Tag::LTSH, Tag::OS_2,
+    Tag::VDMX, Tag::cmap, Tag::cvt,  Tag::fpgm, Tag::gasp,
+    Tag::glyf, Tag::hdmx, Tag::head, Tag::hhea, Tag::hmtx,
+    Tag::loca, Tag::maxp, Tag::name, Tag::post, Tag::prep };
+
+const int64_t TTF_CHECKSUM[] = {
+    0xD463FC48, 0x252028D1, 0x0065078A, 0xC01407B5, 0xFFFF0003,
+    0x9544342B, 0xFC8F16AD, 0x0EC30C7A, 0xA029CD5D, 0x32513087,
+    0x05C323B0, 0x06320195, 0x3B67E701, 0xE7DB08F3, 0xD46E5E89,
+    0xE6EB4A27 };
+
+const int64_t TTF_OFFSET[] = {
+    0x00000198, 0x00001964, 0x000025B0, 0x0002CA74, 0x0002C854,
+    0x00003D34, 0x0000011C, 0x00000154, 0x000001F0, 0x000245D8,
+    0x000025B8, 0x00000178, 0x0002CAB4, 0x00024860, 0x00028854,
+    0x0002C85C };
+
+const int32_t TTF_LENGTH[] = {
+            86,       3146,          8,         64,          8,
+        133284,         54,         36,       6002,        648,
+          6012,         32,        944,      16371,      16383,
+           536 };
+
+const unsigned char TTF_FEAT_DATA[] = {
+    0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+    0, 0, 0, 0x30, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0x34,
+    0, 0, 1, 1, 0, 0xB, 0, 2, 0, 0, 0, 0x38, 0xC0, 0, 1, 2,
+    0, 0, 1, 3, 0, 2, 1, 4, 0, 0, 1, 5, 0, 2, 1, 6 };
+
+}  // namespace sfntly
diff --git a/test/test_data.h b/test/test_data.h
new file mode 100644
index 0000000..d5e576f
--- /dev/null
+++ b/test/test_data.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_TEST_TEST_DATA_H_
+#define SFNTLY_CPP_SRC_TEST_TEST_DATA_H_
+
+#include "sfntly/tag.h"
+
+namespace sfntly {
+
+extern const char* SAMPLE_TTF_FILE;
+extern const char* SAMPLE_BITMAP_FONT;
+
+extern const size_t SAMPLE_TTF_SIZE;
+extern const size_t SAMPLE_TTF_TABLES;
+extern const size_t SAMPLE_TTF_KNOWN_TAGS;
+extern const size_t SAMPLE_BITMAP_KNOWN_TAGS;
+extern const size_t SAMPLE_TTF_FEAT;
+extern const size_t SAMPLE_TTF_HEAD;
+extern const size_t SAMPLE_TTF_POST;
+
+extern const int32_t TTF_KNOWN_TAGS[];
+extern const int32_t BITMAP_KNOWN_TAGS[];
+extern const int64_t TTF_CHECKSUM[];
+extern const int64_t TTF_OFFSET[];
+extern const int32_t TTF_LENGTH[];
+extern const unsigned char TTF_FEAT_DATA[];
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_TEST_TEST_DATA_H_
diff --git a/test/test_font_utils.cc b/test/test_font_utils.cc
new file mode 100644
index 0000000..d59b52b
--- /dev/null
+++ b/test/test_font_utils.cc
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+
+#include "gtest/gtest.h"
+#include "sfntly/data/memory_byte_array.h"
+#include "sfntly/data/growable_memory_byte_array.h"
+#include "sfntly/port/file_input_stream.h"
+#include "test/test_font_utils.h"
+
+namespace sfntly {
+
+void BuilderForFontFile(const char* font_path, FontFactory* factory,
+                        FontBuilderArray* builders) {
+  assert(factory);
+  FileInputStream is;
+  is.Open(font_path);
+  factory->LoadFontsForBuilding(&is, builders);
+  EXPECT_GT(builders->size(), static_cast<size_t>(0));
+}
+
+void SerializeFont(const char* font_path, FontFactory* factory, Font* font) {
+  assert(font_path);
+  assert(factory);
+  assert(font);
+  MemoryOutputStream output_stream;
+  factory->SerializeFont(font, &output_stream);
+  SerializeToFile(&output_stream, font_path);
+}
+
+void LoadFont(const char* font_path, FontFactory* factory, FontArray* fonts) {
+  FileInputStream is;
+  is.Open(font_path);
+  factory->LoadFonts(&is, fonts);
+  is.Close();
+}
+
+void LoadFontUsingByteVector(const char* font_path,
+                            bool fingerprint,
+                            FontArray* fonts) {
+  ByteVector bv;
+  LoadFile(font_path, &bv);
+  FontFactoryPtr factory;
+  factory.Attach(FontFactory::GetInstance());
+  factory->FingerprintFont(fingerprint);
+  factory->LoadFonts(&bv, fonts);
+}
+
+void LoadFile(const char* input_file_path, ByteVector* input_buffer) {
+  assert(input_file_path);
+  assert(input_buffer);
+
+  FILE* input_file = NULL;
+#if defined WIN32
+  fopen_s(&input_file, input_file_path, "rb");
+#else
+  input_file = fopen(input_file_path, "rb");
+#endif
+  EXPECT_NE(input_file, reinterpret_cast<FILE*>(NULL));
+  fseek(input_file, 0, SEEK_END);
+  size_t file_size = ftell(input_file);
+  fseek(input_file, 0, SEEK_SET);
+  input_buffer->resize(file_size);
+  size_t bytes_read = fread(&((*input_buffer)[0]), 1, file_size, input_file);
+  EXPECT_EQ(bytes_read, file_size);
+  fclose(input_file);
+}
+
+void SerializeToFile(MemoryOutputStream* output_stream, const char* file_path) {
+  assert(file_path);
+  assert(output_stream);
+
+  FILE* output_file = NULL;
+#if defined WIN32
+  fopen_s(&output_file, file_path, "wb");
+#else
+  output_file = fopen(file_path, "wb");
+#endif
+  EXPECT_NE(output_file, reinterpret_cast<FILE*>(NULL));
+  fwrite(output_stream->Get(), 1, output_stream->Size(), output_file);
+  fflush(output_file);
+  fclose(output_file);
+}
+
+void HexDump(const unsigned char* byte_data, size_t length) {
+  if (byte_data == NULL || length == 0) {
+    fprintf(stderr, "<NULL>\n");
+    return;
+  }
+
+  fprintf(stderr, "data length = %ld (%lx)\n", length, length);
+  for (size_t i = 0; i < length; ++i) {
+    fprintf(stderr, "%02x ", byte_data[i]);
+    if ((i & 0xf) == 0xf) {
+      fprintf(stderr, "\n");
+    }
+  }
+  fprintf(stderr, "\n");
+}
+
+}  // namespace sfntly
diff --git a/test/test_font_utils.h b/test/test_font_utils.h
new file mode 100644
index 0000000..57fde7a
--- /dev/null
+++ b/test/test_font_utils.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_TEST_TEST_FONT_UTILS_H_
+#define SFNTLY_CPP_SRC_TEST_TEST_FONT_UTILS_H_
+
+#include "sfntly/font.h"
+#include "sfntly/font_factory.h"
+#include "sfntly/port/memory_output_stream.h"
+
+namespace sfntly {
+
+void BuilderForFontFile(const char* font_path, FontFactory* factory,
+                        FontBuilderArray* builders);
+void SerializeFont(const char* font_path, FontFactory* factory, Font* font);
+void LoadFont(const char* font_path, FontFactory* factory, FontArray* fonts);
+void LoadFontUsingByteVector(const char* font_path,
+                            bool fingerprint,
+                            FontArray* fonts);
+
+void LoadFile(const char* input_file_path, ByteVector* input_buffer);
+void SerializeToFile(MemoryOutputStream* output_stream, const char* file_path);
+
+void HexDump(const unsigned char* byte_data, size_t length);
+
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_TEST_TEST_FONT_UTILS_H_
diff --git a/test/test_utils.cc b/test/test_utils.cc
new file mode 100644
index 0000000..4751b92
--- /dev/null
+++ b/test/test_utils.cc
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "test/test_utils.h"
+
+#include <stdio.h>
+#include <unicode/ucnv.h>
+#include <unicode/uchar.h>
+
+#include "gtest/gtest.h"
+#include "sfntly/font.h"
+#include "sfntly/data/memory_byte_array.h"
+#include "sfntly/data/growable_memory_byte_array.h"
+#include "sfntly/port/file_input_stream.h"
+
+namespace sfntly {
+TestUtils::TestUtils() {}
+
+// static
+// OutputStream CreateOutputStream(const char *file_path) {
+// }
+
+// static
+// void TestUtils::CreateNewFile(const char* file_path) {
+// }
+
+// static
+int32_t TestUtils::EncodeOneChar(UConverter* encoder, int16_t uchar) {
+  char* target = new char[ucnv_getMaxCharSize(encoder) * 2];
+  char* target_end;
+  UChar* source = new UChar[2];
+  UChar* source_end;
+  source[0] = (UChar)uchar;
+  source[1] = 0;
+  UErrorCode status = U_ZERO_ERROR;
+  source_end = source;
+  target_end = target;
+  ucnv_fromUnicode(encoder, &target_end, target + 4,
+                   (const UChar**)&source_end, source + sizeof(UChar),
+                   NULL, TRUE, &status);
+  if (!U_SUCCESS(status)) {
+    fprintf(stderr, "Error occured in conversion of %d: %s\n",
+            uchar, u_errorName(status));
+    delete[] source;
+    delete[] target;
+    return 0;
+  }
+  int32_t enc_char = 0;
+  for (int32_t position = 0; position < target_end - target; ++position) {
+    enc_char <<= 8;
+    enc_char |= (target[position] & 0xff);
+  }
+  delete[] source;
+  delete[] target;
+  return enc_char;
+}
+
+// static
+UConverter* TestUtils::GetEncoder(const char* charset_name) {
+  if (charset_name == NULL || strcmp(charset_name, "") == 0)
+    return NULL;
+  UErrorCode status = U_ZERO_ERROR;
+  UConverter* conv = ucnv_open(charset_name, &status);
+  // if (!U_SUCCESS(status))
+  //   return NULL;
+  return conv;  // returns NULL @ error anyway
+}
+
+// Get a file's extension
+// static
+const char* TestUtils::Extension(const char* file_path) {
+  if (!file_path)
+    return NULL;
+  return strrchr(file_path, EXTENSION_SEPARATOR);
+}
+}
diff --git a/test/test_utils.h b/test/test_utils.h
new file mode 100644
index 0000000..af3ffd6
--- /dev/null
+++ b/test/test_utils.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef SFNTLY_CPP_SRC_TEST_TEST_UTILS_H_
+#define SFNTLY_CPP_SRC_TEST_TEST_UTILS_H_
+
+// Must include this before ICU to avoid stdint redefinition issue.
+#include "sfntly/port/type.h"
+
+#include <unicode/ucnv.h>
+
+#include <string>
+
+#include "sfntly/font.h"
+#include "sfntly/data/memory_byte_array.h"
+
+namespace sfntly {
+class TestUtils {
+  TestUtils();
+
+ public:
+  // Compare sections of two byte arrays for equality
+  // @param b1 byte array 1
+  // @param offset1 offset for comparison in byte array 1
+  // @param b2 byte array 2
+  // @param offset2 offset for comparison in byte array 2
+  // @param length the length of the byte arrays to compare
+  // @return true if the array segments are equal; false otherwise
+  // TODO(dfilimon): implement
+  static bool Equals(ByteArray* b1,
+                     int32_t offset1,
+                     ByteArray* b2,
+                     int32_t offset2);
+
+  // @param offset1 offset to start comparing the first ByteArray from
+  // @param ba1 the first ByteArray
+  // @param offset2 offset to start comparing the second ByteArray from
+  // @param ba2 the second ByteArray
+  // @param length the number of bytes to compare
+  // @return true if all bytes in the ranges given are equal; false otherwise
+  // TODO(dfilimon): implement
+  static bool Equals(ByteArray* b1,
+                     int32_t offset1,
+                     ByteArray* b2,
+                     int32_t offset2,
+                     int32_t length);
+
+  // TODO(dfilimon): implement FileOutputStream in port/file_output_stream.*
+  // static OutputStream createOutputStream(const char* file_path);
+
+  // TODO(dfilimon): adapt & implement
+  // static FileChannel createFilechannelForWriting(File file);
+
+  // Creates a new file including deleting an already existing file with the
+  // same path and name and creating any needed directories.
+  // TODO(dfilimon): implement
+  static void CreateNewFile(const char* file_path);
+
+  // Converts an integer into a 4 character string using the ASCII encoding.
+  // @param i the value to convert
+  // @return the String based on the number
+  // TODO(dfilimon): implement
+  static void DumpLongAsString(int32_t i, std::string* result);
+
+  // Calculate an OpenType checksum from the array.
+  // @param b the array to calculate checksum on
+  // @param offset the starting index in the array
+  // @param length the number of bytes to check; must be a multiple of 4
+  // @return checksum
+  // TODO(dfilimon): implement
+  static int64_t CheckSum(ByteArray* b, int32_t offset, int32_t length);
+
+  // Encode a single character in UTF-16.
+  // We only support the BMP for now
+  // @param encoder the encoder to use for the encoding
+  // @param uchar the Unicode character to encode
+  // @return the encoded character
+  static int32_t EncodeOneChar(UConverter* encoder, int16_t uchar);
+
+  // Get an encoder for the charset name.
+  // If the name is null or the empty string then just return null.
+  // @param charsetName the charset to get an encoder for
+  // @return an encoder or null if no encoder available for charset name
+  static UConverter* GetEncoder(const char* charsetName);
+
+ private:
+  static const char EXTENSION_SEPARATOR = '.';
+
+ public:
+  // Get the extension of a file's name.
+  // @param file the whose name to process
+  // @return string containing the extension or an empty string if
+  // there is no extension
+  static const char* Extension(const char* file_path);
+};
+}
+#endif  // SFNTLY_CPP_SRC_TEST_TEST_UTILS_H_
diff --git a/test/test_utils_test.cc b/test/test_utils_test.cc
new file mode 100644
index 0000000..9afc03c
--- /dev/null
+++ b/test/test_utils_test.cc
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+// Must include at the first line to avoid ICU / stdint conflict.
+#include "sfntly/port/type.h"
+
+#include <stdio.h>
+#include <unicode/ucnv.h>
+#include <unicode/uchar.h>
+
+#include "gtest/gtest.h"
+#include "test/test_utils.h"
+
+namespace sfntly {
+
+// Check if proper encoding is being performed
+// Conversion is done from UTF16 to UTF8, SJIS
+bool TestEncoding() {
+  UConverter* conv = TestUtils::GetEncoder("utf8");
+  EXPECT_TRUE(conv != NULL);
+  // Ūnĭcōde̽
+  UChar from[8] = {0x016A, 0x006E, 0x012D, 0x0063, 0x014D, 0x0064, 0x0065,
+                   0x033D};
+  int32_t want[12] = {0xc5, 0xaa, 0x6e, 0xc4, 0xad, 0x63, 0xc5, 0x8d, 0x64,
+                      0x65, 0xcc, 0xbd};
+  int32_t i, j = 0;
+  for (i = 0; i < 7; ++i) {
+    int32_t encoded = TestUtils::EncodeOneChar(conv, (int16_t)from[i]);
+    for (; encoded; encoded <<= 8) {
+      byte_t b = (encoded & 0xff000000) >> 24;
+      if (!b)
+        continue;
+      EXPECT_EQ(want[j], b);
+      if (want[j++] != b) {
+        ucnv_close(conv);
+        return false;
+      }
+    }
+  }
+  ucnv_close(conv);
+  return true;
+}
+
+// Check if the proper extension is obtained
+bool TestExtension() {
+  // usual file name
+  const char *result;
+  result = TestUtils::Extension("../data/ext/tuffy.ttf");
+  EXPECT_EQ(strcmp(result, ".ttf"), 0);
+
+  // more than one 'extension'
+  result = TestUtils::Extension("tuffy.ttf.fake");
+  EXPECT_EQ(strcmp(result, ".fake"), 0);
+
+  // no extension
+  result = TestUtils::Extension("tuffy");
+  EXPECT_STREQ(result, NULL);
+
+  // bogus extension
+  result = TestUtils::Extension("tuffy.");
+  EXPECT_EQ(strcmp(result, "."), 0);
+
+  return true;
+}
+
+}  // namespace sfntly
+
+TEST(TestUtils, All) {
+  ASSERT_TRUE(sfntly::TestExtension());
+  ASSERT_TRUE(sfntly::TestEncoding());
+}
diff --git a/test/test_xml_utils.cc b/test/test_xml_utils.cc
new file mode 100644
index 0000000..dc65add
--- /dev/null
+++ b/test/test_xml_utils.cc
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include <map>
+#include <string>
+#include "test/test_xml_utils.h"
+#include "test/tinyxml/tinyxml.h"
+
+namespace sfntly {
+void InternalGetNodesWithName(const TiXmlNode* node, const std::string& name,
+                              TiXmlNodeVector* wanted_nodes) {
+  if (node->ValueStr() == name)
+    wanted_nodes->push_back(node);
+  for (const TiXmlNode* child = node->FirstChild();
+       child != NULL; child = child->NextSibling()) {
+    InternalGetNodesWithName(child, name, wanted_nodes);
+  }
+}
+
+TiXmlNodeVector* GetNodesWithName(const TiXmlNode* node,
+                                  const std::string& name) {
+  TiXmlNodeVector* wanted_nodes = new TiXmlNodeVector;
+  InternalGetNodesWithName(node, name, wanted_nodes);
+  return wanted_nodes;
+}
+
+const TiXmlAttribute* GetAttribute(const TiXmlNode* node,
+                                   const std::string& name) {
+  for (const TiXmlAttribute* attribute = node->ToElement()->FirstAttribute();
+       attribute != NULL; attribute = attribute->Next()) {
+    if (attribute->Name() == name) {
+      return attribute;
+    }
+  }
+  return NULL;
+}
+}
diff --git a/test/test_xml_utils.h b/test/test_xml_utils.h
new file mode 100644
index 0000000..7a5fe49
--- /dev/null
+++ b/test/test_xml_utils.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "sfntly/port/refcount.h"
+#include "test/tinyxml/tinyxml.h"
+
+#ifndef SFNTLY_CPP_SRC_TEST_TEST_XML_UTILS_H_
+#define SFNTLY_CPP_SRC_TEST_TEST_XML_UTILS_H_
+
+namespace sfntly {
+typedef std::map<std::string, std::string> AttributeMap;
+typedef std::vector<const TiXmlNode*> TiXmlNodeVector;
+
+TiXmlNodeVector* GetNodesWithName(const TiXmlNode* node,
+                                  const std::string& name);
+const TiXmlAttribute* GetAttribute(const TiXmlNode* node,
+                                   const std::string& name);
+}  // namespace sfntly
+
+#endif  // SFNTLY_CPP_SRC_TEST_TEST_XML_UTILS_H_
diff --git a/test/tinyxml/tinystr.cpp b/test/tinyxml/tinystr.cpp
new file mode 100644
index 0000000..0665768
--- /dev/null
+++ b/test/tinyxml/tinystr.cpp
@@ -0,0 +1,111 @@
+/*
+www.sourceforge.net/projects/tinyxml
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any
+purpose, including commercial applications, and to alter it and
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+*/
+
+
+#ifndef TIXML_USE_STL
+
+#include "tinystr.h"
+
+// Error value for find primitive
+const TiXmlString::size_type TiXmlString::npos = static_cast< TiXmlString::size_type >(-1);
+
+
+// Null rep.
+TiXmlString::Rep TiXmlString::nullrep_ = { 0, 0, { '\0' } };
+
+
+void TiXmlString::reserve (size_type cap)
+{
+	if (cap > capacity())
+	{
+		TiXmlString tmp;
+		tmp.init(length(), cap);
+		memcpy(tmp.start(), data(), length());
+		swap(tmp);
+	}
+}
+
+
+TiXmlString& TiXmlString::assign(const char* str, size_type len)
+{
+	size_type cap = capacity();
+	if (len > cap || cap > 3*(len + 8))
+	{
+		TiXmlString tmp;
+		tmp.init(len);
+		memcpy(tmp.start(), str, len);
+		swap(tmp);
+	}
+	else
+	{
+		memmove(start(), str, len);
+		set_size(len);
+	}
+	return *this;
+}
+
+
+TiXmlString& TiXmlString::append(const char* str, size_type len)
+{
+	size_type newsize = length() + len;
+	if (newsize > capacity())
+	{
+		reserve (newsize + capacity());
+	}
+	memmove(finish(), str, len);
+	set_size(newsize);
+	return *this;
+}
+
+
+TiXmlString operator + (const TiXmlString & a, const TiXmlString & b)
+{
+	TiXmlString tmp;
+	tmp.reserve(a.length() + b.length());
+	tmp += a;
+	tmp += b;
+	return tmp;
+}
+
+TiXmlString operator + (const TiXmlString & a, const char* b)
+{
+	TiXmlString tmp;
+	TiXmlString::size_type b_len = static_cast<TiXmlString::size_type>( strlen(b) );
+	tmp.reserve(a.length() + b_len);
+	tmp += a;
+	tmp.append(b, b_len);
+	return tmp;
+}
+
+TiXmlString operator + (const char* a, const TiXmlString & b)
+{
+	TiXmlString tmp;
+	TiXmlString::size_type a_len = static_cast<TiXmlString::size_type>( strlen(a) );
+	tmp.reserve(a_len + b.length());
+	tmp.append(a, a_len);
+	tmp += b;
+	return tmp;
+}
+
+
+#endif	// TIXML_USE_STL
diff --git a/test/tinyxml/tinystr.h b/test/tinyxml/tinystr.h
new file mode 100644
index 0000000..89cca33
--- /dev/null
+++ b/test/tinyxml/tinystr.h
@@ -0,0 +1,305 @@
+/*
+www.sourceforge.net/projects/tinyxml
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any
+purpose, including commercial applications, and to alter it and
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+*/
+
+
+#ifndef TIXML_USE_STL
+
+#ifndef TIXML_STRING_INCLUDED
+#define TIXML_STRING_INCLUDED
+
+#include <assert.h>
+#include <string.h>
+
+/*	The support for explicit isn't that universal, and it isn't really
+	required - it is used to check that the TiXmlString class isn't incorrectly
+	used. Be nice to old compilers and macro it here:
+*/
+#if defined(_MSC_VER) && (_MSC_VER >= 1200 )
+	// Microsoft visual studio, version 6 and higher.
+	#define TIXML_EXPLICIT explicit
+#elif defined(__GNUC__) && (__GNUC__ >= 3 )
+	// GCC version 3 and higher.s
+	#define TIXML_EXPLICIT explicit
+#else
+	#define TIXML_EXPLICIT
+#endif
+
+
+/*
+   TiXmlString is an emulation of a subset of the std::string template.
+   Its purpose is to allow compiling TinyXML on compilers with no or poor STL support.
+   Only the member functions relevant to the TinyXML project have been implemented.
+   The buffer allocation is made by a simplistic power of 2 like mechanism : if we increase
+   a string and there's no more room, we allocate a buffer twice as big as we need.
+*/
+class TiXmlString
+{
+  public :
+	// The size type used
+  	typedef size_t size_type;
+
+	// Error value for find primitive
+	static const size_type npos; // = -1;
+
+
+	// TiXmlString empty constructor
+	TiXmlString () : rep_(&nullrep_)
+	{
+	}
+
+	// TiXmlString copy constructor
+	TiXmlString ( const TiXmlString & copy) : rep_(0)
+	{
+		init(copy.length());
+		memcpy(start(), copy.data(), length());
+	}
+
+	// TiXmlString constructor, based on a string
+	TIXML_EXPLICIT TiXmlString ( const char * copy) : rep_(0)
+	{
+		init( static_cast<size_type>( strlen(copy) ));
+		memcpy(start(), copy, length());
+	}
+
+	// TiXmlString constructor, based on a string
+	TIXML_EXPLICIT TiXmlString ( const char * str, size_type len) : rep_(0)
+	{
+		init(len);
+		memcpy(start(), str, len);
+	}
+
+	// TiXmlString destructor
+	~TiXmlString ()
+	{
+		quit();
+	}
+
+	TiXmlString& operator = (const char * copy)
+	{
+		return assign( copy, (size_type)strlen(copy));
+	}
+
+	TiXmlString& operator = (const TiXmlString & copy)
+	{
+		return assign(copy.start(), copy.length());
+	}
+
+
+	// += operator. Maps to append
+	TiXmlString& operator += (const char * suffix)
+	{
+		return append(suffix, static_cast<size_type>( strlen(suffix) ));
+	}
+
+	// += operator. Maps to append
+	TiXmlString& operator += (char single)
+	{
+		return append(&single, 1);
+	}
+
+	// += operator. Maps to append
+	TiXmlString& operator += (const TiXmlString & suffix)
+	{
+		return append(suffix.data(), suffix.length());
+	}
+
+
+	// Convert a TiXmlString into a null-terminated char *
+	const char * c_str () const { return rep_->str; }
+
+	// Convert a TiXmlString into a char * (need not be null terminated).
+	const char * data () const { return rep_->str; }
+
+	// Return the length of a TiXmlString
+	size_type length () const { return rep_->size; }
+
+	// Alias for length()
+	size_type size () const { return rep_->size; }
+
+	// Checks if a TiXmlString is empty
+	bool empty () const { return rep_->size == 0; }
+
+	// Return capacity of string
+	size_type capacity () const { return rep_->capacity; }
+
+
+	// single char extraction
+	const char& at (size_type index) const
+	{
+		assert( index < length() );
+		return rep_->str[ index ];
+	}
+
+	// [] operator
+	char& operator [] (size_type index) const
+	{
+		assert( index < length() );
+		return rep_->str[ index ];
+	}
+
+	// find a char in a string. Return TiXmlString::npos if not found
+	size_type find (char lookup) const
+	{
+		return find(lookup, 0);
+	}
+
+	// find a char in a string from an offset. Return TiXmlString::npos if not found
+	size_type find (char tofind, size_type offset) const
+	{
+		if (offset >= length()) return npos;
+
+		for (const char* p = c_str() + offset; *p != '\0'; ++p)
+		{
+		   if (*p == tofind) return static_cast< size_type >( p - c_str() );
+		}
+		return npos;
+	}
+
+	void clear ()
+	{
+		//Lee:
+		//The original was just too strange, though correct:
+		//	TiXmlString().swap(*this);
+		//Instead use the quit & re-init:
+		quit();
+		init(0,0);
+	}
+
+	/*	Function to reserve a big amount of data when we know we'll need it. Be aware that this
+		function DOES NOT clear the content of the TiXmlString if any exists.
+	*/
+	void reserve (size_type cap);
+
+	TiXmlString& assign (const char* str, size_type len);
+
+	TiXmlString& append (const char* str, size_type len);
+
+	void swap (TiXmlString& other)
+	{
+		Rep* r = rep_;
+		rep_ = other.rep_;
+		other.rep_ = r;
+	}
+
+  private:
+
+	void init(size_type sz) { init(sz, sz); }
+	void set_size(size_type sz) { rep_->str[ rep_->size = sz ] = '\0'; }
+	char* start() const { return rep_->str; }
+	char* finish() const { return rep_->str + rep_->size; }
+
+	struct Rep
+	{
+		size_type size, capacity;
+		char str[1];
+	};
+
+	void init(size_type sz, size_type cap)
+	{
+		if (cap)
+		{
+			// Lee: the original form:
+			//	rep_ = static_cast<Rep*>(operator new(sizeof(Rep) + cap));
+			// doesn't work in some cases of new being overloaded. Switching
+			// to the normal allocation, although use an 'int' for systems
+			// that are overly picky about structure alignment.
+			const size_type bytesNeeded = sizeof(Rep) + cap;
+			const size_type intsNeeded = ( bytesNeeded + sizeof(int) - 1 ) / sizeof( int ); 
+			rep_ = reinterpret_cast<Rep*>( new int[ intsNeeded ] );
+
+			rep_->str[ rep_->size = sz ] = '\0';
+			rep_->capacity = cap;
+		}
+		else
+		{
+			rep_ = &nullrep_;
+		}
+	}
+
+	void quit()
+	{
+		if (rep_ != &nullrep_)
+		{
+			// The rep_ is really an array of ints. (see the allocator, above).
+			// Cast it back before delete, so the compiler won't incorrectly call destructors.
+			delete [] ( reinterpret_cast<int*>( rep_ ) );
+		}
+	}
+
+	Rep * rep_;
+	static Rep nullrep_;
+
+} ;
+
+
+inline bool operator == (const TiXmlString & a, const TiXmlString & b)
+{
+	return    ( a.length() == b.length() )				// optimization on some platforms
+	       && ( strcmp(a.c_str(), b.c_str()) == 0 );	// actual compare
+}
+inline bool operator < (const TiXmlString & a, const TiXmlString & b)
+{
+	return strcmp(a.c_str(), b.c_str()) < 0;
+}
+
+inline bool operator != (const TiXmlString & a, const TiXmlString & b) { return !(a == b); }
+inline bool operator >  (const TiXmlString & a, const TiXmlString & b) { return b < a; }
+inline bool operator <= (const TiXmlString & a, const TiXmlString & b) { return !(b < a); }
+inline bool operator >= (const TiXmlString & a, const TiXmlString & b) { return !(a < b); }
+
+inline bool operator == (const TiXmlString & a, const char* b) { return strcmp(a.c_str(), b) == 0; }
+inline bool operator == (const char* a, const TiXmlString & b) { return b == a; }
+inline bool operator != (const TiXmlString & a, const char* b) { return !(a == b); }
+inline bool operator != (const char* a, const TiXmlString & b) { return !(b == a); }
+
+TiXmlString operator + (const TiXmlString & a, const TiXmlString & b);
+TiXmlString operator + (const TiXmlString & a, const char* b);
+TiXmlString operator + (const char* a, const TiXmlString & b);
+
+
+/*
+   TiXmlOutStream is an emulation of std::ostream. It is based on TiXmlString.
+   Only the operators that we need for TinyXML have been developped.
+*/
+class TiXmlOutStream : public TiXmlString
+{
+public :
+
+	// TiXmlOutStream << operator.
+	TiXmlOutStream & operator << (const TiXmlString & in)
+	{
+		*this += in;
+		return *this;
+	}
+
+	// TiXmlOutStream << operator.
+	TiXmlOutStream & operator << (const char * in)
+	{
+		*this += in;
+		return *this;
+	}
+
+} ;
+
+#endif	// TIXML_STRING_INCLUDED
+#endif	// TIXML_USE_STL
diff --git a/test/tinyxml/tinyxml.cpp b/test/tinyxml/tinyxml.cpp
new file mode 100644
index 0000000..9c161df
--- /dev/null
+++ b/test/tinyxml/tinyxml.cpp
@@ -0,0 +1,1886 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original code by Lee Thomason (www.grinninglizard.com)
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any
+purpose, including commercial applications, and to alter it and
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+*/
+
+#include <ctype.h>
+
+#ifdef TIXML_USE_STL
+#include <sstream>
+#include <iostream>
+#endif
+
+#include "tinyxml.h"
+
+FILE* TiXmlFOpen( const char* filename, const char* mode );
+
+bool TiXmlBase::condenseWhiteSpace = true;
+
+// Microsoft compiler security
+FILE* TiXmlFOpen( const char* filename, const char* mode )
+{
+	#if defined(_MSC_VER) && (_MSC_VER >= 1400 )
+		FILE* fp = 0;
+		errno_t err = fopen_s( &fp, filename, mode );
+		if ( !err && fp )
+			return fp;
+		return 0;
+	#else
+		return fopen( filename, mode );
+	#endif
+}
+
+void TiXmlBase::EncodeString( const TIXML_STRING& str, TIXML_STRING* outString )
+{
+	int i=0;
+
+	while( i<(int)str.length() )
+	{
+		unsigned char c = (unsigned char) str[i];
+
+		if (    c == '&' 
+		     && i < ( (int)str.length() - 2 )
+			 && str[i+1] == '#'
+			 && str[i+2] == 'x' )
+		{
+			// Hexadecimal character reference.
+			// Pass through unchanged.
+			// &#xA9;	-- copyright symbol, for example.
+			//
+			// The -1 is a bug fix from Rob Laveaux. It keeps
+			// an overflow from happening if there is no ';'.
+			// There are actually 2 ways to exit this loop -
+			// while fails (error case) and break (semicolon found).
+			// However, there is no mechanism (currently) for
+			// this function to return an error.
+			while ( i<(int)str.length()-1 )
+			{
+				outString->append( str.c_str() + i, 1 );
+				++i;
+				if ( str[i] == ';' )
+					break;
+			}
+		}
+		else if ( c == '&' )
+		{
+			outString->append( entity[0].str, entity[0].strLength );
+			++i;
+		}
+		else if ( c == '<' )
+		{
+			outString->append( entity[1].str, entity[1].strLength );
+			++i;
+		}
+		else if ( c == '>' )
+		{
+			outString->append( entity[2].str, entity[2].strLength );
+			++i;
+		}
+		else if ( c == '\"' )
+		{
+			outString->append( entity[3].str, entity[3].strLength );
+			++i;
+		}
+		else if ( c == '\'' )
+		{
+			outString->append( entity[4].str, entity[4].strLength );
+			++i;
+		}
+		else if ( c < 32 )
+		{
+			// Easy pass at non-alpha/numeric/symbol
+			// Below 32 is symbolic.
+			char buf[ 32 ];
+			
+			#if defined(TIXML_SNPRINTF)		
+				TIXML_SNPRINTF( buf, sizeof(buf), "&#x%02X;", (unsigned) ( c & 0xff ) );
+			#else
+				sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) );
+			#endif		
+
+			//*ME:	warning C4267: convert 'size_t' to 'int'
+			//*ME:	Int-Cast to make compiler happy ...
+			outString->append( buf, (int)strlen( buf ) );
+			++i;
+		}
+		else
+		{
+			//char realc = (char) c;
+			//outString->append( &realc, 1 );
+			*outString += (char) c;	// somewhat more efficient function call.
+			++i;
+		}
+	}
+}
+
+
+TiXmlNode::TiXmlNode( NodeType _type ) : TiXmlBase()
+{
+	parent = 0;
+	type = _type;
+	firstChild = 0;
+	lastChild = 0;
+	prev = 0;
+	next = 0;
+}
+
+
+TiXmlNode::~TiXmlNode()
+{
+	TiXmlNode* node = firstChild;
+	TiXmlNode* temp = 0;
+
+	while ( node )
+	{
+		temp = node;
+		node = node->next;
+		delete temp;
+	}	
+}
+
+
+void TiXmlNode::CopyTo( TiXmlNode* target ) const
+{
+	target->SetValue (value.c_str() );
+	target->userData = userData; 
+	target->location = location;
+}
+
+
+void TiXmlNode::Clear()
+{
+	TiXmlNode* node = firstChild;
+	TiXmlNode* temp = 0;
+
+	while ( node )
+	{
+		temp = node;
+		node = node->next;
+		delete temp;
+	}	
+
+	firstChild = 0;
+	lastChild = 0;
+}
+
+
+TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node )
+{
+	assert( node->parent == 0 || node->parent == this );
+	assert( node->GetDocument() == 0 || node->GetDocument() == this->GetDocument() );
+
+	if ( node->Type() == TiXmlNode::TINYXML_DOCUMENT )
+	{
+		delete node;
+		if ( GetDocument() ) 
+			GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return 0;
+	}
+
+	node->parent = this;
+
+	node->prev = lastChild;
+	node->next = 0;
+
+	if ( lastChild )
+		lastChild->next = node;
+	else
+		firstChild = node;			// it was an empty list.
+
+	lastChild = node;
+	return node;
+}
+
+
+TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis )
+{
+	if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT )
+	{
+		if ( GetDocument() ) 
+			GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return 0;
+	}
+	TiXmlNode* node = addThis.Clone();
+	if ( !node )
+		return 0;
+
+	return LinkEndChild( node );
+}
+
+
+TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis )
+{	
+	if ( !beforeThis || beforeThis->parent != this ) {
+		return 0;
+	}
+	if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT )
+	{
+		if ( GetDocument() ) 
+			GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return 0;
+	}
+
+	TiXmlNode* node = addThis.Clone();
+	if ( !node )
+		return 0;
+	node->parent = this;
+
+	node->next = beforeThis;
+	node->prev = beforeThis->prev;
+	if ( beforeThis->prev )
+	{
+		beforeThis->prev->next = node;
+	}
+	else
+	{
+		assert( firstChild == beforeThis );
+		firstChild = node;
+	}
+	beforeThis->prev = node;
+	return node;
+}
+
+
+TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis )
+{
+	if ( !afterThis || afterThis->parent != this ) {
+		return 0;
+	}
+	if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT )
+	{
+		if ( GetDocument() ) 
+			GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return 0;
+	}
+
+	TiXmlNode* node = addThis.Clone();
+	if ( !node )
+		return 0;
+	node->parent = this;
+
+	node->prev = afterThis;
+	node->next = afterThis->next;
+	if ( afterThis->next )
+	{
+		afterThis->next->prev = node;
+	}
+	else
+	{
+		assert( lastChild == afterThis );
+		lastChild = node;
+	}
+	afterThis->next = node;
+	return node;
+}
+
+
+TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis )
+{
+	if ( !replaceThis )
+		return 0;
+
+	if ( replaceThis->parent != this )
+		return 0;
+
+	if ( withThis.ToDocument() ) {
+		// A document can never be a child.	Thanks to Noam.
+		TiXmlDocument* document = GetDocument();
+		if ( document ) 
+			document->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return 0;
+	}
+
+	TiXmlNode* node = withThis.Clone();
+	if ( !node )
+		return 0;
+
+	node->next = replaceThis->next;
+	node->prev = replaceThis->prev;
+
+	if ( replaceThis->next )
+		replaceThis->next->prev = node;
+	else
+		lastChild = node;
+
+	if ( replaceThis->prev )
+		replaceThis->prev->next = node;
+	else
+		firstChild = node;
+
+	delete replaceThis;
+	node->parent = this;
+	return node;
+}
+
+
+bool TiXmlNode::RemoveChild( TiXmlNode* removeThis )
+{
+	if ( !removeThis ) {
+		return false;
+	}
+
+	if ( removeThis->parent != this )
+	{	
+		assert( 0 );
+		return false;
+	}
+
+	if ( removeThis->next )
+		removeThis->next->prev = removeThis->prev;
+	else
+		lastChild = removeThis->prev;
+
+	if ( removeThis->prev )
+		removeThis->prev->next = removeThis->next;
+	else
+		firstChild = removeThis->next;
+
+	delete removeThis;
+	return true;
+}
+
+const TiXmlNode* TiXmlNode::FirstChild( const char * _value ) const
+{
+	const TiXmlNode* node;
+	for ( node = firstChild; node; node = node->next )
+	{
+		if ( strcmp( node->Value(), _value ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+
+const TiXmlNode* TiXmlNode::LastChild( const char * _value ) const
+{
+	const TiXmlNode* node;
+	for ( node = lastChild; node; node = node->prev )
+	{
+		if ( strcmp( node->Value(), _value ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+
+const TiXmlNode* TiXmlNode::IterateChildren( const TiXmlNode* previous ) const
+{
+	if ( !previous )
+	{
+		return FirstChild();
+	}
+	else
+	{
+		assert( previous->parent == this );
+		return previous->NextSibling();
+	}
+}
+
+
+const TiXmlNode* TiXmlNode::IterateChildren( const char * val, const TiXmlNode* previous ) const
+{
+	if ( !previous )
+	{
+		return FirstChild( val );
+	}
+	else
+	{
+		assert( previous->parent == this );
+		return previous->NextSibling( val );
+	}
+}
+
+
+const TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const 
+{
+	const TiXmlNode* node;
+	for ( node = next; node; node = node->next )
+	{
+		if ( strcmp( node->Value(), _value ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+
+const TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const
+{
+	const TiXmlNode* node;
+	for ( node = prev; node; node = node->prev )
+	{
+		if ( strcmp( node->Value(), _value ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+
+void TiXmlElement::RemoveAttribute( const char * name )
+{
+    #ifdef TIXML_USE_STL
+	TIXML_STRING str( name );
+	TiXmlAttribute* node = attributeSet.Find( str );
+	#else
+	TiXmlAttribute* node = attributeSet.Find( name );
+	#endif
+	if ( node )
+	{
+		attributeSet.Remove( node );
+		delete node;
+	}
+}
+
+const TiXmlElement* TiXmlNode::FirstChildElement() const
+{
+	const TiXmlNode* node;
+
+	for (	node = FirstChild();
+			node;
+			node = node->NextSibling() )
+	{
+		if ( node->ToElement() )
+			return node->ToElement();
+	}
+	return 0;
+}
+
+
+const TiXmlElement* TiXmlNode::FirstChildElement( const char * _value ) const
+{
+	const TiXmlNode* node;
+
+	for (	node = FirstChild( _value );
+			node;
+			node = node->NextSibling( _value ) )
+	{
+		if ( node->ToElement() )
+			return node->ToElement();
+	}
+	return 0;
+}
+
+
+const TiXmlElement* TiXmlNode::NextSiblingElement() const
+{
+	const TiXmlNode* node;
+
+	for (	node = NextSibling();
+			node;
+			node = node->NextSibling() )
+	{
+		if ( node->ToElement() )
+			return node->ToElement();
+	}
+	return 0;
+}
+
+
+const TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value ) const
+{
+	const TiXmlNode* node;
+
+	for (	node = NextSibling( _value );
+			node;
+			node = node->NextSibling( _value ) )
+	{
+		if ( node->ToElement() )
+			return node->ToElement();
+	}
+	return 0;
+}
+
+
+const TiXmlDocument* TiXmlNode::GetDocument() const
+{
+	const TiXmlNode* node;
+
+	for( node = this; node; node = node->parent )
+	{
+		if ( node->ToDocument() )
+			return node->ToDocument();
+	}
+	return 0;
+}
+
+
+TiXmlElement::TiXmlElement (const char * _value)
+	: TiXmlNode( TiXmlNode::TINYXML_ELEMENT )
+{
+	firstChild = lastChild = 0;
+	value = _value;
+}
+
+
+#ifdef TIXML_USE_STL
+TiXmlElement::TiXmlElement( const std::string& _value ) 
+	: TiXmlNode( TiXmlNode::TINYXML_ELEMENT )
+{
+	firstChild = lastChild = 0;
+	value = _value;
+}
+#endif
+
+
+TiXmlElement::TiXmlElement( const TiXmlElement& copy)
+	: TiXmlNode( TiXmlNode::TINYXML_ELEMENT )
+{
+	firstChild = lastChild = 0;
+	copy.CopyTo( this );	
+}
+
+
+TiXmlElement& TiXmlElement::operator=( const TiXmlElement& base )
+{
+	ClearThis();
+	base.CopyTo( this );
+	return *this;
+}
+
+
+TiXmlElement::~TiXmlElement()
+{
+	ClearThis();
+}
+
+
+void TiXmlElement::ClearThis()
+{
+	Clear();
+	while( attributeSet.First() )
+	{
+		TiXmlAttribute* node = attributeSet.First();
+		attributeSet.Remove( node );
+		delete node;
+	}
+}
+
+
+const char* TiXmlElement::Attribute( const char* name ) const
+{
+	const TiXmlAttribute* node = attributeSet.Find( name );
+	if ( node )
+		return node->Value();
+	return 0;
+}
+
+
+#ifdef TIXML_USE_STL
+const std::string* TiXmlElement::Attribute( const std::string& name ) const
+{
+	const TiXmlAttribute* attrib = attributeSet.Find( name );
+	if ( attrib )
+		return &attrib->ValueStr();
+	return 0;
+}
+#endif
+
+
+const char* TiXmlElement::Attribute( const char* name, int* i ) const
+{
+	const TiXmlAttribute* attrib = attributeSet.Find( name );
+	const char* result = 0;
+
+	if ( attrib ) {
+		result = attrib->Value();
+		if ( i ) {
+			attrib->QueryIntValue( i );
+		}
+	}
+	return result;
+}
+
+
+#ifdef TIXML_USE_STL
+const std::string* TiXmlElement::Attribute( const std::string& name, int* i ) const
+{
+	const TiXmlAttribute* attrib = attributeSet.Find( name );
+	const std::string* result = 0;
+
+	if ( attrib ) {
+		result = &attrib->ValueStr();
+		if ( i ) {
+			attrib->QueryIntValue( i );
+		}
+	}
+	return result;
+}
+#endif
+
+
+const char* TiXmlElement::Attribute( const char* name, double* d ) const
+{
+	const TiXmlAttribute* attrib = attributeSet.Find( name );
+	const char* result = 0;
+
+	if ( attrib ) {
+		result = attrib->Value();
+		if ( d ) {
+			attrib->QueryDoubleValue( d );
+		}
+	}
+	return result;
+}
+
+
+#ifdef TIXML_USE_STL
+const std::string* TiXmlElement::Attribute( const std::string& name, double* d ) const
+{
+	const TiXmlAttribute* attrib = attributeSet.Find( name );
+	const std::string* result = 0;
+
+	if ( attrib ) {
+		result = &attrib->ValueStr();
+		if ( d ) {
+			attrib->QueryDoubleValue( d );
+		}
+	}
+	return result;
+}
+#endif
+
+
+int TiXmlElement::QueryIntAttribute( const char* name, int* ival ) const
+{
+	const TiXmlAttribute* attrib = attributeSet.Find( name );
+	if ( !attrib )
+		return TIXML_NO_ATTRIBUTE;
+	return attrib->QueryIntValue( ival );
+}
+
+
+int TiXmlElement::QueryUnsignedAttribute( const char* name, unsigned* value ) const
+{
+	const TiXmlAttribute* node = attributeSet.Find( name );
+	if ( !node )
+		return TIXML_NO_ATTRIBUTE;
+
+	int ival = 0;
+	int result = node->QueryIntValue( &ival );
+	*value = (unsigned)ival;
+	return result;
+}
+
+
+int TiXmlElement::QueryBoolAttribute( const char* name, bool* bval ) const
+{
+	const TiXmlAttribute* node = attributeSet.Find( name );
+	if ( !node )
+		return TIXML_NO_ATTRIBUTE;
+	
+	int result = TIXML_WRONG_TYPE;
+	if (    StringEqual( node->Value(), "true", true, TIXML_ENCODING_UNKNOWN ) 
+		 || StringEqual( node->Value(), "yes", true, TIXML_ENCODING_UNKNOWN ) 
+		 || StringEqual( node->Value(), "1", true, TIXML_ENCODING_UNKNOWN ) ) 
+	{
+		*bval = true;
+		result = TIXML_SUCCESS;
+	}
+	else if (    StringEqual( node->Value(), "false", true, TIXML_ENCODING_UNKNOWN ) 
+			  || StringEqual( node->Value(), "no", true, TIXML_ENCODING_UNKNOWN ) 
+			  || StringEqual( node->Value(), "0", true, TIXML_ENCODING_UNKNOWN ) ) 
+	{
+		*bval = false;
+		result = TIXML_SUCCESS;
+	}
+	return result;
+}
+
+
+
+#ifdef TIXML_USE_STL
+int TiXmlElement::QueryIntAttribute( const std::string& name, int* ival ) const
+{
+	const TiXmlAttribute* attrib = attributeSet.Find( name );
+	if ( !attrib )
+		return TIXML_NO_ATTRIBUTE;
+	return attrib->QueryIntValue( ival );
+}
+#endif
+
+
+int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const
+{
+	const TiXmlAttribute* attrib = attributeSet.Find( name );
+	if ( !attrib )
+		return TIXML_NO_ATTRIBUTE;
+	return attrib->QueryDoubleValue( dval );
+}
+
+
+#ifdef TIXML_USE_STL
+int TiXmlElement::QueryDoubleAttribute( const std::string& name, double* dval ) const
+{
+	const TiXmlAttribute* attrib = attributeSet.Find( name );
+	if ( !attrib )
+		return TIXML_NO_ATTRIBUTE;
+	return attrib->QueryDoubleValue( dval );
+}
+#endif
+
+
+void TiXmlElement::SetAttribute( const char * name, int val )
+{	
+	TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
+	if ( attrib ) {
+		attrib->SetIntValue( val );
+	}
+}
+
+
+#ifdef TIXML_USE_STL
+void TiXmlElement::SetAttribute( const std::string& name, int val )
+{	
+	TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
+	if ( attrib ) {
+		attrib->SetIntValue( val );
+	}
+}
+#endif
+
+
+void TiXmlElement::SetDoubleAttribute( const char * name, double val )
+{	
+	TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
+	if ( attrib ) {
+		attrib->SetDoubleValue( val );
+	}
+}
+
+
+#ifdef TIXML_USE_STL
+void TiXmlElement::SetDoubleAttribute( const std::string& name, double val )
+{	
+	TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
+	if ( attrib ) {
+		attrib->SetDoubleValue( val );
+	}
+}
+#endif 
+
+
+void TiXmlElement::SetAttribute( const char * cname, const char * cvalue )
+{
+	TiXmlAttribute* attrib = attributeSet.FindOrCreate( cname );
+	if ( attrib ) {
+		attrib->SetValue( cvalue );
+	}
+}
+
+
+#ifdef TIXML_USE_STL
+void TiXmlElement::SetAttribute( const std::string& _name, const std::string& _value )
+{
+	TiXmlAttribute* attrib = attributeSet.FindOrCreate( _name );
+	if ( attrib ) {
+		attrib->SetValue( _value );
+	}
+}
+#endif
+
+
+void TiXmlElement::Print( FILE* cfile, int depth ) const
+{
+	int i;
+	assert( cfile );
+	for ( i=0; i<depth; i++ ) {
+		fprintf( cfile, "    " );
+	}
+
+	fprintf( cfile, "<%s", value.c_str() );
+
+	const TiXmlAttribute* attrib;
+	for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() )
+	{
+		fprintf( cfile, " " );
+		attrib->Print( cfile, depth );
+	}
+
+	// There are 3 different formatting approaches:
+	// 1) An element without children is printed as a <foo /> node
+	// 2) An element with only a text child is printed as <foo> text </foo>
+	// 3) An element with children is printed on multiple lines.
+	TiXmlNode* node;
+	if ( !firstChild )
+	{
+		fprintf( cfile, " />" );
+	}
+	else if ( firstChild == lastChild && firstChild->ToText() )
+	{
+		fprintf( cfile, ">" );
+		firstChild->Print( cfile, depth + 1 );
+		fprintf( cfile, "</%s>", value.c_str() );
+	}
+	else
+	{
+		fprintf( cfile, ">" );
+
+		for ( node = firstChild; node; node=node->NextSibling() )
+		{
+			if ( !node->ToText() )
+			{
+				fprintf( cfile, "\n" );
+			}
+			node->Print( cfile, depth+1 );
+		}
+		fprintf( cfile, "\n" );
+		for( i=0; i<depth; ++i ) {
+			fprintf( cfile, "    " );
+		}
+		fprintf( cfile, "</%s>", value.c_str() );
+	}
+}
+
+
+void TiXmlElement::CopyTo( TiXmlElement* target ) const
+{
+	// superclass:
+	TiXmlNode::CopyTo( target );
+
+	// Element class: 
+	// Clone the attributes, then clone the children.
+	const TiXmlAttribute* attribute = 0;
+	for(	attribute = attributeSet.First();
+	attribute;
+	attribute = attribute->Next() )
+	{
+		target->SetAttribute( attribute->Name(), attribute->Value() );
+	}
+
+	TiXmlNode* node = 0;
+	for ( node = firstChild; node; node = node->NextSibling() )
+	{
+		target->LinkEndChild( node->Clone() );
+	}
+}
+
+bool TiXmlElement::Accept( TiXmlVisitor* visitor ) const
+{
+	if ( visitor->VisitEnter( *this, attributeSet.First() ) ) 
+	{
+		for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
+		{
+			if ( !node->Accept( visitor ) )
+				break;
+		}
+	}
+	return visitor->VisitExit( *this );
+}
+
+
+TiXmlNode* TiXmlElement::Clone() const
+{
+	TiXmlElement* clone = new TiXmlElement( Value() );
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+const char* TiXmlElement::GetText() const
+{
+	const TiXmlNode* child = this->FirstChild();
+	if ( child ) {
+		const TiXmlText* childText = child->ToText();
+		if ( childText ) {
+			return childText->Value();
+		}
+	}
+	return 0;
+}
+
+
+TiXmlDocument::TiXmlDocument() : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
+{
+	tabsize = 4;
+	useMicrosoftBOM = false;
+	ClearError();
+}
+
+TiXmlDocument::TiXmlDocument( const char * documentName ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
+{
+	tabsize = 4;
+	useMicrosoftBOM = false;
+	value = documentName;
+	ClearError();
+}
+
+
+#ifdef TIXML_USE_STL
+TiXmlDocument::TiXmlDocument( const std::string& documentName ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
+{
+	tabsize = 4;
+	useMicrosoftBOM = false;
+    value = documentName;
+	ClearError();
+}
+#endif
+
+
+TiXmlDocument::TiXmlDocument( const TiXmlDocument& copy ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
+{
+	copy.CopyTo( this );
+}
+
+
+TiXmlDocument& TiXmlDocument::operator=( const TiXmlDocument& copy )
+{
+	Clear();
+	copy.CopyTo( this );
+	return *this;
+}
+
+
+bool TiXmlDocument::LoadFile( TiXmlEncoding encoding )
+{
+	return LoadFile( Value(), encoding );
+}
+
+
+bool TiXmlDocument::SaveFile() const
+{
+	return SaveFile( Value() );
+}
+
+bool TiXmlDocument::LoadFile( const char* _filename, TiXmlEncoding encoding )
+{
+	TIXML_STRING filename( _filename );
+	value = filename;
+
+	// reading in binary mode so that tinyxml can normalize the EOL
+	FILE* file = TiXmlFOpen( value.c_str (), "rb" );	
+
+	if ( file )
+	{
+		bool result = LoadFile( file, encoding );
+		fclose( file );
+		return result;
+	}
+	else
+	{
+		SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return false;
+	}
+}
+
+bool TiXmlDocument::LoadFile( FILE* file, TiXmlEncoding encoding )
+{
+	if ( !file ) 
+	{
+		SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return false;
+	}
+
+	// Delete the existing data:
+	Clear();
+	location.Clear();
+
+	// Get the file size, so we can pre-allocate the string. HUGE speed impact.
+	long length = 0;
+	fseek( file, 0, SEEK_END );
+	length = ftell( file );
+	fseek( file, 0, SEEK_SET );
+
+	// Strange case, but good to handle up front.
+	if ( length <= 0 )
+	{
+		SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return false;
+	}
+
+	// Subtle bug here. TinyXml did use fgets. But from the XML spec:
+	// 2.11 End-of-Line Handling
+	// <snip>
+	// <quote>
+	// ...the XML processor MUST behave as if it normalized all line breaks in external 
+	// parsed entities (including the document entity) on input, before parsing, by translating 
+	// both the two-character sequence #xD #xA and any #xD that is not followed by #xA to 
+	// a single #xA character.
+	// </quote>
+	//
+	// It is not clear fgets does that, and certainly isn't clear it works cross platform. 
+	// Generally, you expect fgets to translate from the convention of the OS to the c/unix
+	// convention, and not work generally.
+
+	/*
+	while( fgets( buf, sizeof(buf), file ) )
+	{
+		data += buf;
+	}
+	*/
+
+	char* buf = new char[ length+1 ];
+	buf[0] = 0;
+
+	if ( fread( buf, length, 1, file ) != 1 ) {
+		delete [] buf;
+		SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return false;
+	}
+
+	// Process the buffer in place to normalize new lines. (See comment above.)
+	// Copies from the 'p' to 'q' pointer, where p can advance faster if
+	// a newline-carriage return is hit.
+	//
+	// Wikipedia:
+	// Systems based on ASCII or a compatible character set use either LF  (Line feed, '\n', 0x0A, 10 in decimal) or 
+	// CR (Carriage return, '\r', 0x0D, 13 in decimal) individually, or CR followed by LF (CR+LF, 0x0D 0x0A)...
+	//		* LF:    Multics, Unix and Unix-like systems (GNU/Linux, AIX, Xenix, Mac OS X, FreeBSD, etc.), BeOS, Amiga, RISC OS, and others
+    //		* CR+LF: DEC RT-11 and most other early non-Unix, non-IBM OSes, CP/M, MP/M, DOS, OS/2, Microsoft Windows, Symbian OS
+    //		* CR:    Commodore 8-bit machines, Apple II family, Mac OS up to version 9 and OS-9
+
+	const char* p = buf;	// the read head
+	char* q = buf;			// the write head
+	const char CR = 0x0d;
+	const char LF = 0x0a;
+
+	buf[length] = 0;
+	while( *p ) {
+		assert( p < (buf+length) );
+		assert( q <= (buf+length) );
+		assert( q <= p );
+
+		if ( *p == CR ) {
+			*q++ = LF;
+			p++;
+			if ( *p == LF ) {		// check for CR+LF (and skip LF)
+				p++;
+			}
+		}
+		else {
+			*q++ = *p++;
+		}
+	}
+	assert( q <= (buf+length) );
+	*q = 0;
+
+	Parse( buf, 0, encoding );
+
+	delete [] buf;
+	return !Error();
+}
+
+
+bool TiXmlDocument::SaveFile( const char * filename ) const
+{
+	// The old c stuff lives on...
+	FILE* fp = TiXmlFOpen( filename, "w" );
+	if ( fp )
+	{
+		bool result = SaveFile( fp );
+		fclose( fp );
+		return result;
+	}
+	return false;
+}
+
+
+bool TiXmlDocument::SaveFile( FILE* fp ) const
+{
+	if ( useMicrosoftBOM ) 
+	{
+		const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
+		const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
+		const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
+
+		fputc( TIXML_UTF_LEAD_0, fp );
+		fputc( TIXML_UTF_LEAD_1, fp );
+		fputc( TIXML_UTF_LEAD_2, fp );
+	}
+	Print( fp, 0 );
+	return (ferror(fp) == 0);
+}
+
+
+void TiXmlDocument::CopyTo( TiXmlDocument* target ) const
+{
+	TiXmlNode::CopyTo( target );
+
+	target->error = error;
+	target->errorId = errorId;
+	target->errorDesc = errorDesc;
+	target->tabsize = tabsize;
+	target->errorLocation = errorLocation;
+	target->useMicrosoftBOM = useMicrosoftBOM;
+
+	TiXmlNode* node = 0;
+	for ( node = firstChild; node; node = node->NextSibling() )
+	{
+		target->LinkEndChild( node->Clone() );
+	}	
+}
+
+
+TiXmlNode* TiXmlDocument::Clone() const
+{
+	TiXmlDocument* clone = new TiXmlDocument();
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+void TiXmlDocument::Print( FILE* cfile, int depth ) const
+{
+	assert( cfile );
+	for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
+	{
+		node->Print( cfile, depth );
+		fprintf( cfile, "\n" );
+	}
+}
+
+
+bool TiXmlDocument::Accept( TiXmlVisitor* visitor ) const
+{
+	if ( visitor->VisitEnter( *this ) )
+	{
+		for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
+		{
+			if ( !node->Accept( visitor ) )
+				break;
+		}
+	}
+	return visitor->VisitExit( *this );
+}
+
+
+const TiXmlAttribute* TiXmlAttribute::Next() const
+{
+	// We are using knowledge of the sentinel. The sentinel
+	// have a value or name.
+	if ( next->value.empty() && next->name.empty() )
+		return 0;
+	return next;
+}
+
+/*
+TiXmlAttribute* TiXmlAttribute::Next()
+{
+	// We are using knowledge of the sentinel. The sentinel
+	// have a value or name.
+	if ( next->value.empty() && next->name.empty() )
+		return 0;
+	return next;
+}
+*/
+
+const TiXmlAttribute* TiXmlAttribute::Previous() const
+{
+	// We are using knowledge of the sentinel. The sentinel
+	// have a value or name.
+	if ( prev->value.empty() && prev->name.empty() )
+		return 0;
+	return prev;
+}
+
+/*
+TiXmlAttribute* TiXmlAttribute::Previous()
+{
+	// We are using knowledge of the sentinel. The sentinel
+	// have a value or name.
+	if ( prev->value.empty() && prev->name.empty() )
+		return 0;
+	return prev;
+}
+*/
+
+void TiXmlAttribute::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const
+{
+	TIXML_STRING n, v;
+
+	EncodeString( name, &n );
+	EncodeString( value, &v );
+
+	if (value.find ('\"') == TIXML_STRING::npos) {
+		if ( cfile ) {
+			fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() );
+		}
+		if ( str ) {
+			(*str) += n; (*str) += "=\""; (*str) += v; (*str) += "\"";
+		}
+	}
+	else {
+		if ( cfile ) {
+			fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() );
+		}
+		if ( str ) {
+			(*str) += n; (*str) += "='"; (*str) += v; (*str) += "'";
+		}
+	}
+}
+
+
+int TiXmlAttribute::QueryIntValue( int* ival ) const
+{
+	if ( TIXML_SSCANF( value.c_str(), "%d", ival ) == 1 )
+		return TIXML_SUCCESS;
+	return TIXML_WRONG_TYPE;
+}
+
+int TiXmlAttribute::QueryDoubleValue( double* dval ) const
+{
+	if ( TIXML_SSCANF( value.c_str(), "%lf", dval ) == 1 )
+		return TIXML_SUCCESS;
+	return TIXML_WRONG_TYPE;
+}
+
+void TiXmlAttribute::SetIntValue( int _value )
+{
+	char buf [64];
+	#if defined(TIXML_SNPRINTF)		
+		TIXML_SNPRINTF(buf, sizeof(buf), "%d", _value);
+	#else
+		sprintf (buf, "%d", _value);
+	#endif
+	SetValue (buf);
+}
+
+void TiXmlAttribute::SetDoubleValue( double _value )
+{
+	char buf [256];
+	#if defined(TIXML_SNPRINTF)		
+		TIXML_SNPRINTF( buf, sizeof(buf), "%g", _value);
+	#else
+		sprintf (buf, "%g", _value);
+	#endif
+	SetValue (buf);
+}
+
+int TiXmlAttribute::IntValue() const
+{
+	return atoi (value.c_str ());
+}
+
+double  TiXmlAttribute::DoubleValue() const
+{
+	return atof (value.c_str ());
+}
+
+
+TiXmlComment::TiXmlComment( const TiXmlComment& copy ) : TiXmlNode( TiXmlNode::TINYXML_COMMENT )
+{
+	copy.CopyTo( this );
+}
+
+
+TiXmlComment& TiXmlComment::operator=( const TiXmlComment& base )
+{
+	Clear();
+	base.CopyTo( this );
+	return *this;
+}
+
+
+void TiXmlComment::Print( FILE* cfile, int depth ) const
+{
+	assert( cfile );
+	for ( int i=0; i<depth; i++ )
+	{
+		fprintf( cfile,  "    " );
+	}
+	fprintf( cfile, "<!--%s-->", value.c_str() );
+}
+
+
+void TiXmlComment::CopyTo( TiXmlComment* target ) const
+{
+	TiXmlNode::CopyTo( target );
+}
+
+
+bool TiXmlComment::Accept( TiXmlVisitor* visitor ) const
+{
+	return visitor->Visit( *this );
+}
+
+
+TiXmlNode* TiXmlComment::Clone() const
+{
+	TiXmlComment* clone = new TiXmlComment();
+
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+void TiXmlText::Print( FILE* cfile, int depth ) const
+{
+	assert( cfile );
+	if ( cdata )
+	{
+		int i;
+		fprintf( cfile, "\n" );
+		for ( i=0; i<depth; i++ ) {
+			fprintf( cfile, "    " );
+		}
+		fprintf( cfile, "<![CDATA[%s]]>\n", value.c_str() );	// unformatted output
+	}
+	else
+	{
+		TIXML_STRING buffer;
+		EncodeString( value, &buffer );
+		fprintf( cfile, "%s", buffer.c_str() );
+	}
+}
+
+
+void TiXmlText::CopyTo( TiXmlText* target ) const
+{
+	TiXmlNode::CopyTo( target );
+	target->cdata = cdata;
+}
+
+
+bool TiXmlText::Accept( TiXmlVisitor* visitor ) const
+{
+	return visitor->Visit( *this );
+}
+
+
+TiXmlNode* TiXmlText::Clone() const
+{	
+	TiXmlText* clone = 0;
+	clone = new TiXmlText( "" );
+
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+TiXmlDeclaration::TiXmlDeclaration( const char * _version,
+									const char * _encoding,
+									const char * _standalone )
+	: TiXmlNode( TiXmlNode::TINYXML_DECLARATION )
+{
+	version = _version;
+	encoding = _encoding;
+	standalone = _standalone;
+}
+
+
+#ifdef TIXML_USE_STL
+TiXmlDeclaration::TiXmlDeclaration(	const std::string& _version,
+									const std::string& _encoding,
+									const std::string& _standalone )
+	: TiXmlNode( TiXmlNode::TINYXML_DECLARATION )
+{
+	version = _version;
+	encoding = _encoding;
+	standalone = _standalone;
+}
+#endif
+
+
+TiXmlDeclaration::TiXmlDeclaration( const TiXmlDeclaration& copy )
+	: TiXmlNode( TiXmlNode::TINYXML_DECLARATION )
+{
+	copy.CopyTo( this );	
+}
+
+
+TiXmlDeclaration& TiXmlDeclaration::operator=( const TiXmlDeclaration& copy )
+{
+	Clear();
+	copy.CopyTo( this );
+	return *this;
+}
+
+
+void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const
+{
+	if ( cfile ) fprintf( cfile, "<?xml " );
+	if ( str )	 (*str) += "<?xml ";
+
+	if ( !version.empty() ) {
+		if ( cfile ) fprintf (cfile, "version=\"%s\" ", version.c_str ());
+		if ( str ) { (*str) += "version=\""; (*str) += version; (*str) += "\" "; }
+	}
+	if ( !encoding.empty() ) {
+		if ( cfile ) fprintf (cfile, "encoding=\"%s\" ", encoding.c_str ());
+		if ( str ) { (*str) += "encoding=\""; (*str) += encoding; (*str) += "\" "; }
+	}
+	if ( !standalone.empty() ) {
+		if ( cfile ) fprintf (cfile, "standalone=\"%s\" ", standalone.c_str ());
+		if ( str ) { (*str) += "standalone=\""; (*str) += standalone; (*str) += "\" "; }
+	}
+	if ( cfile ) fprintf( cfile, "?>" );
+	if ( str )	 (*str) += "?>";
+}
+
+
+void TiXmlDeclaration::CopyTo( TiXmlDeclaration* target ) const
+{
+	TiXmlNode::CopyTo( target );
+
+	target->version = version;
+	target->encoding = encoding;
+	target->standalone = standalone;
+}
+
+
+bool TiXmlDeclaration::Accept( TiXmlVisitor* visitor ) const
+{
+	return visitor->Visit( *this );
+}
+
+
+TiXmlNode* TiXmlDeclaration::Clone() const
+{	
+	TiXmlDeclaration* clone = new TiXmlDeclaration();
+
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+void TiXmlUnknown::Print( FILE* cfile, int depth ) const
+{
+	for ( int i=0; i<depth; i++ )
+		fprintf( cfile, "    " );
+	fprintf( cfile, "<%s>", value.c_str() );
+}
+
+
+void TiXmlUnknown::CopyTo( TiXmlUnknown* target ) const
+{
+	TiXmlNode::CopyTo( target );
+}
+
+
+bool TiXmlUnknown::Accept( TiXmlVisitor* visitor ) const
+{
+	return visitor->Visit( *this );
+}
+
+
+TiXmlNode* TiXmlUnknown::Clone() const
+{
+	TiXmlUnknown* clone = new TiXmlUnknown();
+
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+TiXmlAttributeSet::TiXmlAttributeSet()
+{
+	sentinel.next = &sentinel;
+	sentinel.prev = &sentinel;
+}
+
+
+TiXmlAttributeSet::~TiXmlAttributeSet()
+{
+	assert( sentinel.next == &sentinel );
+	assert( sentinel.prev == &sentinel );
+}
+
+
+void TiXmlAttributeSet::Add( TiXmlAttribute* addMe )
+{
+    #ifdef TIXML_USE_STL
+	assert( !Find( TIXML_STRING( addMe->Name() ) ) );	// Shouldn't be multiply adding to the set.
+	#else
+	assert( !Find( addMe->Name() ) );	// Shouldn't be multiply adding to the set.
+	#endif
+
+	addMe->next = &sentinel;
+	addMe->prev = sentinel.prev;
+
+	sentinel.prev->next = addMe;
+	sentinel.prev      = addMe;
+}
+
+void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe )
+{
+	TiXmlAttribute* node;
+
+	for( node = sentinel.next; node != &sentinel; node = node->next )
+	{
+		if ( node == removeMe )
+		{
+			node->prev->next = node->next;
+			node->next->prev = node->prev;
+			node->next = 0;
+			node->prev = 0;
+			return;
+		}
+	}
+	assert( 0 );		// we tried to remove a non-linked attribute.
+}
+
+
+#ifdef TIXML_USE_STL
+TiXmlAttribute* TiXmlAttributeSet::Find( const std::string& name ) const
+{
+	for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
+	{
+		if ( node->name == name )
+			return node;
+	}
+	return 0;
+}
+
+TiXmlAttribute* TiXmlAttributeSet::FindOrCreate( const std::string& _name )
+{
+	TiXmlAttribute* attrib = Find( _name );
+	if ( !attrib ) {
+		attrib = new TiXmlAttribute();
+		Add( attrib );
+		attrib->SetName( _name );
+	}
+	return attrib;
+}
+#endif
+
+
+TiXmlAttribute* TiXmlAttributeSet::Find( const char* name ) const
+{
+	for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
+	{
+		if ( strcmp( node->name.c_str(), name ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+
+TiXmlAttribute* TiXmlAttributeSet::FindOrCreate( const char* _name )
+{
+	TiXmlAttribute* attrib = Find( _name );
+	if ( !attrib ) {
+		attrib = new TiXmlAttribute();
+		Add( attrib );
+		attrib->SetName( _name );
+	}
+	return attrib;
+}
+
+
+#ifdef TIXML_USE_STL	
+std::istream& operator>> (std::istream & in, TiXmlNode & base)
+{
+	TIXML_STRING tag;
+	tag.reserve( 8 * 1000 );
+	base.StreamIn( &in, &tag );
+
+	base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING );
+	return in;
+}
+#endif
+
+
+#ifdef TIXML_USE_STL	
+std::ostream& operator<< (std::ostream & out, const TiXmlNode & base)
+{
+	TiXmlPrinter printer;
+	printer.SetStreamPrinting();
+	base.Accept( &printer );
+	out << printer.Str();
+
+	return out;
+}
+
+
+std::string& operator<< (std::string& out, const TiXmlNode& base )
+{
+	TiXmlPrinter printer;
+	printer.SetStreamPrinting();
+	base.Accept( &printer );
+	out.append( printer.Str() );
+
+	return out;
+}
+#endif
+
+
+TiXmlHandle TiXmlHandle::FirstChild() const
+{
+	if ( node )
+	{
+		TiXmlNode* child = node->FirstChild();
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::FirstChild( const char * value ) const
+{
+	if ( node )
+	{
+		TiXmlNode* child = node->FirstChild( value );
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::FirstChildElement() const
+{
+	if ( node )
+	{
+		TiXmlElement* child = node->FirstChildElement();
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::FirstChildElement( const char * value ) const
+{
+	if ( node )
+	{
+		TiXmlElement* child = node->FirstChildElement( value );
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::Child( int count ) const
+{
+	if ( node )
+	{
+		int i;
+		TiXmlNode* child = node->FirstChild();
+		for (	i=0;
+				child && i<count;
+				child = child->NextSibling(), ++i )
+		{
+			// nothing
+		}
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::Child( const char* value, int count ) const
+{
+	if ( node )
+	{
+		int i;
+		TiXmlNode* child = node->FirstChild( value );
+		for (	i=0;
+				child && i<count;
+				child = child->NextSibling( value ), ++i )
+		{
+			// nothing
+		}
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::ChildElement( int count ) const
+{
+	if ( node )
+	{
+		int i;
+		TiXmlElement* child = node->FirstChildElement();
+		for (	i=0;
+				child && i<count;
+				child = child->NextSiblingElement(), ++i )
+		{
+			// nothing
+		}
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::ChildElement( const char* value, int count ) const
+{
+	if ( node )
+	{
+		int i;
+		TiXmlElement* child = node->FirstChildElement( value );
+		for (	i=0;
+				child && i<count;
+				child = child->NextSiblingElement( value ), ++i )
+		{
+			// nothing
+		}
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+bool TiXmlPrinter::VisitEnter( const TiXmlDocument& )
+{
+	return true;
+}
+
+bool TiXmlPrinter::VisitExit( const TiXmlDocument& )
+{
+	return true;
+}
+
+bool TiXmlPrinter::VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute )
+{
+	DoIndent();
+	buffer += "<";
+	buffer += element.Value();
+
+	for( const TiXmlAttribute* attrib = firstAttribute; attrib; attrib = attrib->Next() )
+	{
+		buffer += " ";
+		attrib->Print( 0, 0, &buffer );
+	}
+
+	if ( !element.FirstChild() ) 
+	{
+		buffer += " />";
+		DoLineBreak();
+	}
+	else 
+	{
+		buffer += ">";
+		if (    element.FirstChild()->ToText()
+			  && element.LastChild() == element.FirstChild()
+			  && element.FirstChild()->ToText()->CDATA() == false )
+		{
+			simpleTextPrint = true;
+			// no DoLineBreak()!
+		}
+		else
+		{
+			DoLineBreak();
+		}
+	}
+	++depth;	
+	return true;
+}
+
+
+bool TiXmlPrinter::VisitExit( const TiXmlElement& element )
+{
+	--depth;
+	if ( !element.FirstChild() ) 
+	{
+		// nothing.
+	}
+	else 
+	{
+		if ( simpleTextPrint )
+		{
+			simpleTextPrint = false;
+		}
+		else
+		{
+			DoIndent();
+		}
+		buffer += "</";
+		buffer += element.Value();
+		buffer += ">";
+		DoLineBreak();
+	}
+	return true;
+}
+
+
+bool TiXmlPrinter::Visit( const TiXmlText& text )
+{
+	if ( text.CDATA() )
+	{
+		DoIndent();
+		buffer += "<![CDATA[";
+		buffer += text.Value();
+		buffer += "]]>";
+		DoLineBreak();
+	}
+	else if ( simpleTextPrint )
+	{
+		TIXML_STRING str;
+		TiXmlBase::EncodeString( text.ValueTStr(), &str );
+		buffer += str;
+	}
+	else
+	{
+		DoIndent();
+		TIXML_STRING str;
+		TiXmlBase::EncodeString( text.ValueTStr(), &str );
+		buffer += str;
+		DoLineBreak();
+	}
+	return true;
+}
+
+
+bool TiXmlPrinter::Visit( const TiXmlDeclaration& declaration )
+{
+	DoIndent();
+	declaration.Print( 0, 0, &buffer );
+	DoLineBreak();
+	return true;
+}
+
+
+bool TiXmlPrinter::Visit( const TiXmlComment& comment )
+{
+	DoIndent();
+	buffer += "<!--";
+	buffer += comment.Value();
+	buffer += "-->";
+	DoLineBreak();
+	return true;
+}
+
+
+bool TiXmlPrinter::Visit( const TiXmlUnknown& unknown )
+{
+	DoIndent();
+	buffer += "<";
+	buffer += unknown.Value();
+	buffer += ">";
+	DoLineBreak();
+	return true;
+}
+
diff --git a/test/tinyxml/tinyxml.h b/test/tinyxml/tinyxml.h
new file mode 100644
index 0000000..a3589e5
--- /dev/null
+++ b/test/tinyxml/tinyxml.h
@@ -0,0 +1,1805 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original code by Lee Thomason (www.grinninglizard.com)
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any
+purpose, including commercial applications, and to alter it and
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+*/
+
+
+#ifndef TINYXML_INCLUDED
+#define TINYXML_INCLUDED
+
+#ifdef _MSC_VER
+#pragma warning( push )
+#pragma warning( disable : 4530 )
+#pragma warning( disable : 4786 )
+#endif
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+// Help out windows:
+#if defined( _DEBUG ) && !defined( DEBUG )
+#define DEBUG
+#endif
+
+#ifdef TIXML_USE_STL
+	#include <string>
+ 	#include <iostream>
+	#include <sstream>
+	#define TIXML_STRING		std::string
+#else
+	#include "tinystr.h"
+	#define TIXML_STRING		TiXmlString
+#endif
+
+// Deprecated library function hell. Compilers want to use the
+// new safe versions. This probably doesn't fully address the problem,
+// but it gets closer. There are too many compilers for me to fully
+// test. If you get compilation troubles, undefine TIXML_SAFE
+#define TIXML_SAFE
+
+#ifdef TIXML_SAFE
+	#if defined(_MSC_VER) && (_MSC_VER >= 1400 )
+		// Microsoft visual studio, version 2005 and higher.
+		#define TIXML_SNPRINTF _snprintf_s
+		#define TIXML_SSCANF   sscanf_s
+	#elif defined(_MSC_VER) && (_MSC_VER >= 1200 )
+		// Microsoft visual studio, version 6 and higher.
+		//#pragma message( "Using _sn* functions." )
+		#define TIXML_SNPRINTF _snprintf
+		#define TIXML_SSCANF   sscanf
+	#elif defined(__GNUC__) && (__GNUC__ >= 3 )
+		// GCC version 3 and higher.s
+		//#warning( "Using sn* functions." )
+		#define TIXML_SNPRINTF snprintf
+		#define TIXML_SSCANF   sscanf
+	#else
+		#define TIXML_SNPRINTF snprintf
+		#define TIXML_SSCANF   sscanf
+	#endif
+#endif	
+
+class TiXmlDocument;
+class TiXmlElement;
+class TiXmlComment;
+class TiXmlUnknown;
+class TiXmlAttribute;
+class TiXmlText;
+class TiXmlDeclaration;
+class TiXmlParsingData;
+
+const int TIXML_MAJOR_VERSION = 2;
+const int TIXML_MINOR_VERSION = 6;
+const int TIXML_PATCH_VERSION = 2;
+
+/*	Internal structure for tracking location of items 
+	in the XML file.
+*/
+struct TiXmlCursor
+{
+	TiXmlCursor()		{ Clear(); }
+	void Clear()		{ row = col = -1; }
+
+	int row;	// 0 based.
+	int col;	// 0 based.
+};
+
+
+/**
+	Implements the interface to the "Visitor pattern" (see the Accept() method.)
+	If you call the Accept() method, it requires being passed a TiXmlVisitor
+	class to handle callbacks. For nodes that contain other nodes (Document, Element)
+	you will get called with a VisitEnter/VisitExit pair. Nodes that are always leaves
+	are simply called with Visit().
+
+	If you return 'true' from a Visit method, recursive parsing will continue. If you return
+	false, <b>no children of this node or its sibilings</b> will be Visited.
+
+	All flavors of Visit methods have a default implementation that returns 'true' (continue 
+	visiting). You need to only override methods that are interesting to you.
+
+	Generally Accept() is called on the TiXmlDocument, although all nodes suppert Visiting.
+
+	You should never change the document from a callback.
+
+	@sa TiXmlNode::Accept()
+*/
+class TiXmlVisitor
+{
+public:
+	virtual ~TiXmlVisitor() {}
+
+	/// Visit a document.
+	virtual bool VisitEnter( const TiXmlDocument& /*doc*/ )			{ return true; }
+	/// Visit a document.
+	virtual bool VisitExit( const TiXmlDocument& /*doc*/ )			{ return true; }
+
+	/// Visit an element.
+	virtual bool VisitEnter( const TiXmlElement& /*element*/, const TiXmlAttribute* /*firstAttribute*/ )	{ return true; }
+	/// Visit an element.
+	virtual bool VisitExit( const TiXmlElement& /*element*/ )		{ return true; }
+
+	/// Visit a declaration
+	virtual bool Visit( const TiXmlDeclaration& /*declaration*/ )	{ return true; }
+	/// Visit a text node
+	virtual bool Visit( const TiXmlText& /*text*/ )					{ return true; }
+	/// Visit a comment node
+	virtual bool Visit( const TiXmlComment& /*comment*/ )			{ return true; }
+	/// Visit an unknown node
+	virtual bool Visit( const TiXmlUnknown& /*unknown*/ )			{ return true; }
+};
+
+// Only used by Attribute::Query functions
+enum 
+{ 
+	TIXML_SUCCESS,
+	TIXML_NO_ATTRIBUTE,
+	TIXML_WRONG_TYPE
+};
+
+
+// Used by the parsing routines.
+enum TiXmlEncoding
+{
+	TIXML_ENCODING_UNKNOWN,
+	TIXML_ENCODING_UTF8,
+	TIXML_ENCODING_LEGACY
+};
+
+const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN;
+
+/** TiXmlBase is a base class for every class in TinyXml.
+	It does little except to establish that TinyXml classes
+	can be printed and provide some utility functions.
+
+	In XML, the document and elements can contain
+	other elements and other types of nodes.
+
+	@verbatim
+	A Document can contain:	Element	(container or leaf)
+							Comment (leaf)
+							Unknown (leaf)
+							Declaration( leaf )
+
+	An Element can contain:	Element (container or leaf)
+							Text	(leaf)
+							Attributes (not on tree)
+							Comment (leaf)
+							Unknown (leaf)
+
+	A Decleration contains: Attributes (not on tree)
+	@endverbatim
+*/
+class TiXmlBase
+{
+	friend class TiXmlNode;
+	friend class TiXmlElement;
+	friend class TiXmlDocument;
+
+public:
+	TiXmlBase()	:	userData(0)		{}
+	virtual ~TiXmlBase()			{}
+
+	/**	All TinyXml classes can print themselves to a filestream
+		or the string class (TiXmlString in non-STL mode, std::string
+		in STL mode.) Either or both cfile and str can be null.
+		
+		This is a formatted print, and will insert 
+		tabs and newlines.
+		
+		(For an unformatted stream, use the << operator.)
+	*/
+	virtual void Print( FILE* cfile, int depth ) const = 0;
+
+	/**	The world does not agree on whether white space should be kept or
+		not. In order to make everyone happy, these global, static functions
+		are provided to set whether or not TinyXml will condense all white space
+		into a single space or not. The default is to condense. Note changing this
+		value is not thread safe.
+	*/
+	static void SetCondenseWhiteSpace( bool condense )		{ condenseWhiteSpace = condense; }
+
+	/// Return the current white space setting.
+	static bool IsWhiteSpaceCondensed()						{ return condenseWhiteSpace; }
+
+	/** Return the position, in the original source file, of this node or attribute.
+		The row and column are 1-based. (That is the first row and first column is
+		1,1). If the returns values are 0 or less, then the parser does not have
+		a row and column value.
+
+		Generally, the row and column value will be set when the TiXmlDocument::Load(),
+		TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set
+		when the DOM was created from operator>>.
+
+		The values reflect the initial load. Once the DOM is modified programmatically
+		(by adding or changing nodes and attributes) the new values will NOT update to
+		reflect changes in the document.
+
+		There is a minor performance cost to computing the row and column. Computation
+		can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value.
+
+		@sa TiXmlDocument::SetTabSize()
+	*/
+	int Row() const			{ return location.row + 1; }
+	int Column() const		{ return location.col + 1; }	///< See Row()
+
+	void  SetUserData( void* user )			{ userData = user; }	///< Set a pointer to arbitrary user data.
+	void* GetUserData()						{ return userData; }	///< Get a pointer to arbitrary user data.
+	const void* GetUserData() const 		{ return userData; }	///< Get a pointer to arbitrary user data.
+
+	// Table that returs, for a given lead byte, the total number of bytes
+	// in the UTF-8 sequence.
+	static const int utf8ByteTable[256];
+
+	virtual const char* Parse(	const char* p, 
+								TiXmlParsingData* data, 
+								TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0;
+
+	/** Expands entities in a string. Note this should not contian the tag's '<', '>', etc, 
+		or they will be transformed into entities!
+	*/
+	static void EncodeString( const TIXML_STRING& str, TIXML_STRING* out );
+
+	enum
+	{
+		TIXML_NO_ERROR = 0,
+		TIXML_ERROR,
+		TIXML_ERROR_OPENING_FILE,
+		TIXML_ERROR_PARSING_ELEMENT,
+		TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,
+		TIXML_ERROR_READING_ELEMENT_VALUE,
+		TIXML_ERROR_READING_ATTRIBUTES,
+		TIXML_ERROR_PARSING_EMPTY,
+		TIXML_ERROR_READING_END_TAG,
+		TIXML_ERROR_PARSING_UNKNOWN,
+		TIXML_ERROR_PARSING_COMMENT,
+		TIXML_ERROR_PARSING_DECLARATION,
+		TIXML_ERROR_DOCUMENT_EMPTY,
+		TIXML_ERROR_EMBEDDED_NULL,
+		TIXML_ERROR_PARSING_CDATA,
+		TIXML_ERROR_DOCUMENT_TOP_ONLY,
+
+		TIXML_ERROR_STRING_COUNT
+	};
+
+protected:
+
+	static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding );
+
+	inline static bool IsWhiteSpace( char c )		
+	{ 
+		return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' ); 
+	}
+	inline static bool IsWhiteSpace( int c )
+	{
+		if ( c < 256 )
+			return IsWhiteSpace( (char) c );
+		return false;	// Again, only truly correct for English/Latin...but usually works.
+	}
+
+	#ifdef TIXML_USE_STL
+	static bool	StreamWhiteSpace( std::istream * in, TIXML_STRING * tag );
+	static bool StreamTo( std::istream * in, int character, TIXML_STRING * tag );
+	#endif
+
+	/*	Reads an XML name into the string provided. Returns
+		a pointer just past the last character of the name,
+		or 0 if the function has an error.
+	*/
+	static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding );
+
+	/*	Reads text. Returns a pointer past the given end tag.
+		Wickedly complex options, but it keeps the (sensitive) code in one place.
+	*/
+	static const char* ReadText(	const char* in,				// where to start
+									TIXML_STRING* text,			// the string read
+									bool ignoreWhiteSpace,		// whether to keep the white space
+									const char* endTag,			// what ends this text
+									bool ignoreCase,			// whether to ignore case in the end tag
+									TiXmlEncoding encoding );	// the current encoding
+
+	// If an entity has been found, transform it into a character.
+	static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding );
+
+	// Get a character, while interpreting entities.
+	// The length can be from 0 to 4 bytes.
+	inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding )
+	{
+		assert( p );
+		if ( encoding == TIXML_ENCODING_UTF8 )
+		{
+			*length = utf8ByteTable[ *((const unsigned char*)p) ];
+			assert( *length >= 0 && *length < 5 );
+		}
+		else
+		{
+			*length = 1;
+		}
+
+		if ( *length == 1 )
+		{
+			if ( *p == '&' )
+				return GetEntity( p, _value, length, encoding );
+			*_value = *p;
+			return p+1;
+		}
+		else if ( *length )
+		{
+			//strncpy( _value, p, *length );	// lots of compilers don't like this function (unsafe),
+												// and the null terminator isn't needed
+			for( int i=0; p[i] && i<*length; ++i ) {
+				_value[i] = p[i];
+			}
+			return p + (*length);
+		}
+		else
+		{
+			// Not valid text.
+			return 0;
+		}
+	}
+
+	// Return true if the next characters in the stream are any of the endTag sequences.
+	// Ignore case only works for english, and should only be relied on when comparing
+	// to English words: StringEqual( p, "version", true ) is fine.
+	static bool StringEqual(	const char* p,
+								const char* endTag,
+								bool ignoreCase,
+								TiXmlEncoding encoding );
+
+	static const char* errorString[ TIXML_ERROR_STRING_COUNT ];
+
+	TiXmlCursor location;
+
+    /// Field containing a generic user pointer
+	void*			userData;
+	
+	// None of these methods are reliable for any language except English.
+	// Good for approximation, not great for accuracy.
+	static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding );
+	static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding );
+	inline static int ToLower( int v, TiXmlEncoding encoding )
+	{
+		if ( encoding == TIXML_ENCODING_UTF8 )
+		{
+			if ( v < 128 ) return tolower( v );
+			return v;
+		}
+		else
+		{
+			return tolower( v );
+		}
+	}
+	static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
+
+private:
+	TiXmlBase( const TiXmlBase& );				// not implemented.
+	void operator=( const TiXmlBase& base );	// not allowed.
+
+	struct Entity
+	{
+		const char*     str;
+		unsigned int	strLength;
+		char		    chr;
+	};
+	enum
+	{
+		NUM_ENTITY = 5,
+		MAX_ENTITY_LENGTH = 6
+
+	};
+	static Entity entity[ NUM_ENTITY ];
+	static bool condenseWhiteSpace;
+};
+
+
+/** The parent class for everything in the Document Object Model.
+	(Except for attributes).
+	Nodes have siblings, a parent, and children. A node can be
+	in a document, or stand on its own. The type of a TiXmlNode
+	can be queried, and it can be cast to its more defined type.
+*/
+class TiXmlNode : public TiXmlBase
+{
+	friend class TiXmlDocument;
+	friend class TiXmlElement;
+
+public:
+	#ifdef TIXML_USE_STL	
+
+	    /** An input stream operator, for every class. Tolerant of newlines and
+		    formatting, but doesn't expect them.
+	    */
+	    friend std::istream& operator >> (std::istream& in, TiXmlNode& base);
+
+	    /** An output stream operator, for every class. Note that this outputs
+		    without any newlines or formatting, as opposed to Print(), which
+		    includes tabs and new lines.
+
+		    The operator<< and operator>> are not completely symmetric. Writing
+		    a node to a stream is very well defined. You'll get a nice stream
+		    of output, without any extra whitespace or newlines.
+		    
+		    But reading is not as well defined. (As it always is.) If you create
+		    a TiXmlElement (for example) and read that from an input stream,
+		    the text needs to define an element or junk will result. This is
+		    true of all input streams, but it's worth keeping in mind.
+
+		    A TiXmlDocument will read nodes until it reads a root element, and
+			all the children of that root element.
+	    */	
+	    friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base);
+
+		/// Appends the XML node or attribute to a std::string.
+		friend std::string& operator<< (std::string& out, const TiXmlNode& base );
+
+	#endif
+
+	/** The types of XML nodes supported by TinyXml. (All the
+			unsupported types are picked up by UNKNOWN.)
+	*/
+	enum NodeType
+	{
+		TINYXML_DOCUMENT,
+		TINYXML_ELEMENT,
+		TINYXML_COMMENT,
+		TINYXML_UNKNOWN,
+		TINYXML_TEXT,
+		TINYXML_DECLARATION,
+		TINYXML_TYPECOUNT
+	};
+
+	virtual ~TiXmlNode();
+
+	/** The meaning of 'value' changes for the specific type of
+		TiXmlNode.
+		@verbatim
+		Document:	filename of the xml file
+		Element:	name of the element
+		Comment:	the comment text
+		Unknown:	the tag contents
+		Text:		the text string
+		@endverbatim
+
+		The subclasses will wrap this function.
+	*/
+	const char *Value() const { return value.c_str (); }
+
+    #ifdef TIXML_USE_STL
+	/** Return Value() as a std::string. If you only use STL,
+	    this is more efficient than calling Value().
+		Only available in STL mode.
+	*/
+	const std::string& ValueStr() const { return value; }
+	#endif
+
+	const TIXML_STRING& ValueTStr() const { return value; }
+
+	/** Changes the value of the node. Defined as:
+		@verbatim
+		Document:	filename of the xml file
+		Element:	name of the element
+		Comment:	the comment text
+		Unknown:	the tag contents
+		Text:		the text string
+		@endverbatim
+	*/
+	void SetValue(const char * _value) { value = _value;}
+
+    #ifdef TIXML_USE_STL
+	/// STL std::string form.
+	void SetValue( const std::string& _value )	{ value = _value; }
+	#endif
+
+	/// Delete all the children of this node. Does not affect 'this'.
+	void Clear();
+
+	/// One step up the DOM.
+	TiXmlNode* Parent()							{ return parent; }
+	const TiXmlNode* Parent() const				{ return parent; }
+
+	const TiXmlNode* FirstChild()	const		{ return firstChild; }	///< The first child of this node. Will be null if there are no children.
+	TiXmlNode* FirstChild()						{ return firstChild; }
+	const TiXmlNode* FirstChild( const char * value ) const;			///< The first child of this node with the matching 'value'. Will be null if none found.
+	/// The first child of this node with the matching 'value'. Will be null if none found.
+	TiXmlNode* FirstChild( const char * _value ) {
+		// Call through to the const version - safe since nothing is changed. Exiting syntax: cast this to a const (always safe)
+		// call the method, cast the return back to non-const.
+		return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->FirstChild( _value ));
+	}
+	const TiXmlNode* LastChild() const	{ return lastChild; }		/// The last child of this node. Will be null if there are no children.
+	TiXmlNode* LastChild()	{ return lastChild; }
+	
+	const TiXmlNode* LastChild( const char * value ) const;			/// The last child of this node matching 'value'. Will be null if there are no children.
+	TiXmlNode* LastChild( const char * _value ) {
+		return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value ));
+	}
+
+    #ifdef TIXML_USE_STL
+	const TiXmlNode* FirstChild( const std::string& _value ) const	{	return FirstChild (_value.c_str ());	}	///< STL std::string form.
+	TiXmlNode* FirstChild( const std::string& _value )				{	return FirstChild (_value.c_str ());	}	///< STL std::string form.
+	const TiXmlNode* LastChild( const std::string& _value ) const	{	return LastChild (_value.c_str ());	}	///< STL std::string form.
+	TiXmlNode* LastChild( const std::string& _value )				{	return LastChild (_value.c_str ());	}	///< STL std::string form.
+	#endif
+
+	/** An alternate way to walk the children of a node.
+		One way to iterate over nodes is:
+		@verbatim
+			for( child = parent->FirstChild(); child; child = child->NextSibling() )
+		@endverbatim
+
+		IterateChildren does the same thing with the syntax:
+		@verbatim
+			child = 0;
+			while( child = parent->IterateChildren( child ) )
+		@endverbatim
+
+		IterateChildren takes the previous child as input and finds
+		the next one. If the previous child is null, it returns the
+		first. IterateChildren will return null when done.
+	*/
+	const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const;
+	TiXmlNode* IterateChildren( const TiXmlNode* previous ) {
+		return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( previous ) );
+	}
+
+	/// This flavor of IterateChildren searches for children with a particular 'value'
+	const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const;
+	TiXmlNode* IterateChildren( const char * _value, const TiXmlNode* previous ) {
+		return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( _value, previous ) );
+	}
+
+    #ifdef TIXML_USE_STL
+	const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const	{	return IterateChildren (_value.c_str (), previous);	}	///< STL std::string form.
+	TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) {	return IterateChildren (_value.c_str (), previous);	}	///< STL std::string form.
+	#endif
+
+	/** Add a new node related to this. Adds a child past the LastChild.
+		Returns a pointer to the new object or NULL if an error occured.
+	*/
+	TiXmlNode* InsertEndChild( const TiXmlNode& addThis );
+
+
+	/** Add a new node related to this. Adds a child past the LastChild.
+
+		NOTE: the node to be added is passed by pointer, and will be
+		henceforth owned (and deleted) by tinyXml. This method is efficient
+		and avoids an extra copy, but should be used with care as it
+		uses a different memory model than the other insert functions.
+
+		@sa InsertEndChild
+	*/
+	TiXmlNode* LinkEndChild( TiXmlNode* addThis );
+
+	/** Add a new node related to this. Adds a child before the specified child.
+		Returns a pointer to the new object or NULL if an error occured.
+	*/
+	TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
+
+	/** Add a new node related to this. Adds a child after the specified child.
+		Returns a pointer to the new object or NULL if an error occured.
+	*/
+	TiXmlNode* InsertAfterChild(  TiXmlNode* afterThis, const TiXmlNode& addThis );
+
+	/** Replace a child of this node.
+		Returns a pointer to the new object or NULL if an error occured.
+	*/
+	TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
+
+	/// Delete a child of this node.
+	bool RemoveChild( TiXmlNode* removeThis );
+
+	/// Navigate to a sibling node.
+	const TiXmlNode* PreviousSibling() const			{ return prev; }
+	TiXmlNode* PreviousSibling()						{ return prev; }
+
+	/// Navigate to a sibling node.
+	const TiXmlNode* PreviousSibling( const char * ) const;
+	TiXmlNode* PreviousSibling( const char *_prev ) {
+		return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->PreviousSibling( _prev ) );
+	}
+
+    #ifdef TIXML_USE_STL
+	const TiXmlNode* PreviousSibling( const std::string& _value ) const	{	return PreviousSibling (_value.c_str ());	}	///< STL std::string form.
+	TiXmlNode* PreviousSibling( const std::string& _value ) 			{	return PreviousSibling (_value.c_str ());	}	///< STL std::string form.
+	const TiXmlNode* NextSibling( const std::string& _value) const		{	return NextSibling (_value.c_str ());	}	///< STL std::string form.
+	TiXmlNode* NextSibling( const std::string& _value) 					{	return NextSibling (_value.c_str ());	}	///< STL std::string form.
+	#endif
+
+	/// Navigate to a sibling node.
+	const TiXmlNode* NextSibling() const				{ return next; }
+	TiXmlNode* NextSibling()							{ return next; }
+
+	/// Navigate to a sibling node with the given 'value'.
+	const TiXmlNode* NextSibling( const char * ) const;
+	TiXmlNode* NextSibling( const char* _next ) {
+		return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->NextSibling( _next ) );
+	}
+
+	/** Convenience function to get through elements.
+		Calls NextSibling and ToElement. Will skip all non-Element
+		nodes. Returns 0 if there is not another element.
+	*/
+	const TiXmlElement* NextSiblingElement() const;
+	TiXmlElement* NextSiblingElement() {
+		return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement() );
+	}
+
+	/** Convenience function to get through elements.
+		Calls NextSibling and ToElement. Will skip all non-Element
+		nodes. Returns 0 if there is not another element.
+	*/
+	const TiXmlElement* NextSiblingElement( const char * ) const;
+	TiXmlElement* NextSiblingElement( const char *_next ) {
+		return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement( _next ) );
+	}
+
+    #ifdef TIXML_USE_STL
+	const TiXmlElement* NextSiblingElement( const std::string& _value) const	{	return NextSiblingElement (_value.c_str ());	}	///< STL std::string form.
+	TiXmlElement* NextSiblingElement( const std::string& _value)				{	return NextSiblingElement (_value.c_str ());	}	///< STL std::string form.
+	#endif
+
+	/// Convenience function to get through elements.
+	const TiXmlElement* FirstChildElement()	const;
+	TiXmlElement* FirstChildElement() {
+		return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement() );
+	}
+
+	/// Convenience function to get through elements.
+	const TiXmlElement* FirstChildElement( const char * _value ) const;
+	TiXmlElement* FirstChildElement( const char * _value ) {
+		return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement( _value ) );
+	}
+
+    #ifdef TIXML_USE_STL
+	const TiXmlElement* FirstChildElement( const std::string& _value ) const	{	return FirstChildElement (_value.c_str ());	}	///< STL std::string form.
+	TiXmlElement* FirstChildElement( const std::string& _value )				{	return FirstChildElement (_value.c_str ());	}	///< STL std::string form.
+	#endif
+
+	/** Query the type (as an enumerated value, above) of this node.
+		The possible types are: TINYXML_DOCUMENT, TINYXML_ELEMENT, TINYXML_COMMENT,
+								TINYXML_UNKNOWN, TINYXML_TEXT, and TINYXML_DECLARATION.
+	*/
+	int Type() const	{ return type; }
+
+	/** Return a pointer to the Document this node lives in.
+		Returns null if not in a document.
+	*/
+	const TiXmlDocument* GetDocument() const;
+	TiXmlDocument* GetDocument() {
+		return const_cast< TiXmlDocument* >( (const_cast< const TiXmlNode* >(this))->GetDocument() );
+	}
+
+	/// Returns true if this node has no children.
+	bool NoChildren() const						{ return !firstChild; }
+
+	virtual const TiXmlDocument*    ToDocument()    const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual const TiXmlElement*     ToElement()     const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual const TiXmlComment*     ToComment()     const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual const TiXmlUnknown*     ToUnknown()     const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual const TiXmlText*        ToText()        const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual const TiXmlDeclaration* ToDeclaration() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+
+	virtual TiXmlDocument*          ToDocument()    { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual TiXmlElement*           ToElement()	    { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual TiXmlComment*           ToComment()     { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual TiXmlUnknown*           ToUnknown()	    { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual TiXmlText*	            ToText()        { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual TiXmlDeclaration*       ToDeclaration() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+
+	/** Create an exact duplicate of this node and return it. The memory must be deleted
+		by the caller. 
+	*/
+	virtual TiXmlNode* Clone() const = 0;
+
+	/** Accept a hierchical visit the nodes in the TinyXML DOM. Every node in the 
+		XML tree will be conditionally visited and the host will be called back
+		via the TiXmlVisitor interface.
+
+		This is essentially a SAX interface for TinyXML. (Note however it doesn't re-parse
+		the XML for the callbacks, so the performance of TinyXML is unchanged by using this
+		interface versus any other.)
+
+		The interface has been based on ideas from:
+
+		- http://www.saxproject.org/
+		- http://c2.com/cgi/wiki?HierarchicalVisitorPattern 
+
+		Which are both good references for "visiting".
+
+		An example of using Accept():
+		@verbatim
+		TiXmlPrinter printer;
+		tinyxmlDoc.Accept( &printer );
+		const char* xmlcstr = printer.CStr();
+		@endverbatim
+	*/
+	virtual bool Accept( TiXmlVisitor* visitor ) const = 0;
+
+protected:
+	TiXmlNode( NodeType _type );
+
+	// Copy to the allocated object. Shared functionality between Clone, Copy constructor,
+	// and the assignment operator.
+	void CopyTo( TiXmlNode* target ) const;
+
+	#ifdef TIXML_USE_STL
+	    // The real work of the input operator.
+	virtual void StreamIn( std::istream* in, TIXML_STRING* tag ) = 0;
+	#endif
+
+	// Figure out what is at *p, and parse it. Returns null if it is not an xml node.
+	TiXmlNode* Identify( const char* start, TiXmlEncoding encoding );
+
+	TiXmlNode*		parent;
+	NodeType		type;
+
+	TiXmlNode*		firstChild;
+	TiXmlNode*		lastChild;
+
+	TIXML_STRING	value;
+
+	TiXmlNode*		prev;
+	TiXmlNode*		next;
+
+private:
+	TiXmlNode( const TiXmlNode& );				// not implemented.
+	void operator=( const TiXmlNode& base );	// not allowed.
+};
+
+
+/** An attribute is a name-value pair. Elements have an arbitrary
+	number of attributes, each with a unique name.
+
+	@note The attributes are not TiXmlNodes, since they are not
+		  part of the tinyXML document object model. There are other
+		  suggested ways to look at this problem.
+*/
+class TiXmlAttribute : public TiXmlBase
+{
+	friend class TiXmlAttributeSet;
+
+public:
+	/// Construct an empty attribute.
+	TiXmlAttribute() : TiXmlBase()
+	{
+		document = 0;
+		prev = next = 0;
+	}
+
+	#ifdef TIXML_USE_STL
+	/// std::string constructor.
+	TiXmlAttribute( const std::string& _name, const std::string& _value )
+	{
+		name = _name;
+		value = _value;
+		document = 0;
+		prev = next = 0;
+	}
+	#endif
+
+	/// Construct an attribute with a name and value.
+	TiXmlAttribute( const char * _name, const char * _value )
+	{
+		name = _name;
+		value = _value;
+		document = 0;
+		prev = next = 0;
+	}
+
+	const char*		Name()  const		{ return name.c_str(); }		///< Return the name of this attribute.
+	const char*		Value() const		{ return value.c_str(); }		///< Return the value of this attribute.
+	#ifdef TIXML_USE_STL
+	const std::string& ValueStr() const	{ return value; }				///< Return the value of this attribute.
+	#endif
+	int				IntValue() const;									///< Return the value of this attribute, converted to an integer.
+	double			DoubleValue() const;								///< Return the value of this attribute, converted to a double.
+
+	// Get the tinyxml string representation
+	const TIXML_STRING& NameTStr() const { return name; }
+
+	/** QueryIntValue examines the value string. It is an alternative to the
+		IntValue() method with richer error checking.
+		If the value is an integer, it is stored in 'value' and 
+		the call returns TIXML_SUCCESS. If it is not
+		an integer, it returns TIXML_WRONG_TYPE.
+
+		A specialized but useful call. Note that for success it returns 0,
+		which is the opposite of almost all other TinyXml calls.
+	*/
+	int QueryIntValue( int* _value ) const;
+	/// QueryDoubleValue examines the value string. See QueryIntValue().
+	int QueryDoubleValue( double* _value ) const;
+
+	void SetName( const char* _name )	{ name = _name; }				///< Set the name of this attribute.
+	void SetValue( const char* _value )	{ value = _value; }				///< Set the value.
+
+	void SetIntValue( int _value );										///< Set the value from an integer.
+	void SetDoubleValue( double _value );								///< Set the value from a double.
+
+    #ifdef TIXML_USE_STL
+	/// STL std::string form.
+	void SetName( const std::string& _name )	{ name = _name; }	
+	/// STL std::string form.	
+	void SetValue( const std::string& _value )	{ value = _value; }
+	#endif
+
+	/// Get the next sibling attribute in the DOM. Returns null at end.
+	const TiXmlAttribute* Next() const;
+	TiXmlAttribute* Next() {
+		return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() ); 
+	}
+
+	/// Get the previous sibling attribute in the DOM. Returns null at beginning.
+	const TiXmlAttribute* Previous() const;
+	TiXmlAttribute* Previous() {
+		return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() ); 
+	}
+
+	bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; }
+	bool operator<( const TiXmlAttribute& rhs )	 const { return name < rhs.name; }
+	bool operator>( const TiXmlAttribute& rhs )  const { return name > rhs.name; }
+
+	/*	Attribute parsing starts: first letter of the name
+						 returns: the next char after the value end quote
+	*/
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+	// Prints this Attribute to a FILE stream.
+	virtual void Print( FILE* cfile, int depth ) const {
+		Print( cfile, depth, 0 );
+	}
+	void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
+
+	// [internal use]
+	// Set the document pointer so the attribute can report errors.
+	void SetDocument( TiXmlDocument* doc )	{ document = doc; }
+
+private:
+	TiXmlAttribute( const TiXmlAttribute& );				// not implemented.
+	void operator=( const TiXmlAttribute& base );	// not allowed.
+
+	TiXmlDocument*	document;	// A pointer back to a document, for error reporting.
+	TIXML_STRING name;
+	TIXML_STRING value;
+	TiXmlAttribute*	prev;
+	TiXmlAttribute*	next;
+};
+
+
+/*	A class used to manage a group of attributes.
+	It is only used internally, both by the ELEMENT and the DECLARATION.
+	
+	The set can be changed transparent to the Element and Declaration
+	classes that use it, but NOT transparent to the Attribute
+	which has to implement a next() and previous() method. Which makes
+	it a bit problematic and prevents the use of STL.
+
+	This version is implemented with circular lists because:
+		- I like circular lists
+		- it demonstrates some independence from the (typical) doubly linked list.
+*/
+class TiXmlAttributeSet
+{
+public:
+	TiXmlAttributeSet();
+	~TiXmlAttributeSet();
+
+	void Add( TiXmlAttribute* attribute );
+	void Remove( TiXmlAttribute* attribute );
+
+	const TiXmlAttribute* First()	const	{ return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
+	TiXmlAttribute* First()					{ return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
+	const TiXmlAttribute* Last() const		{ return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
+	TiXmlAttribute* Last()					{ return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
+
+	TiXmlAttribute*	Find( const char* _name ) const;
+	TiXmlAttribute* FindOrCreate( const char* _name );
+
+#	ifdef TIXML_USE_STL
+	TiXmlAttribute*	Find( const std::string& _name ) const;
+	TiXmlAttribute* FindOrCreate( const std::string& _name );
+#	endif
+
+
+private:
+	//*ME:	Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element),
+	//*ME:	this class must be also use a hidden/disabled copy-constructor !!!
+	TiXmlAttributeSet( const TiXmlAttributeSet& );	// not allowed
+	void operator=( const TiXmlAttributeSet& );	// not allowed (as TiXmlAttribute)
+
+	TiXmlAttribute sentinel;
+};
+
+
+/** The element is a container class. It has a value, the element name,
+	and can contain other elements, text, comments, and unknowns.
+	Elements also contain an arbitrary number of attributes.
+*/
+class TiXmlElement : public TiXmlNode
+{
+public:
+	/// Construct an element.
+	TiXmlElement (const char * in_value);
+
+	#ifdef TIXML_USE_STL
+	/// std::string constructor.
+	TiXmlElement( const std::string& _value );
+	#endif
+
+	TiXmlElement( const TiXmlElement& );
+
+	TiXmlElement& operator=( const TiXmlElement& base );
+
+	virtual ~TiXmlElement();
+
+	/** Given an attribute name, Attribute() returns the value
+		for the attribute of that name, or null if none exists.
+	*/
+	const char* Attribute( const char* name ) const;
+
+	/** Given an attribute name, Attribute() returns the value
+		for the attribute of that name, or null if none exists.
+		If the attribute exists and can be converted to an integer,
+		the integer value will be put in the return 'i', if 'i'
+		is non-null.
+	*/
+	const char* Attribute( const char* name, int* i ) const;
+
+	/** Given an attribute name, Attribute() returns the value
+		for the attribute of that name, or null if none exists.
+		If the attribute exists and can be converted to an double,
+		the double value will be put in the return 'd', if 'd'
+		is non-null.
+	*/
+	const char* Attribute( const char* name, double* d ) const;
+
+	/** QueryIntAttribute examines the attribute - it is an alternative to the
+		Attribute() method with richer error checking.
+		If the attribute is an integer, it is stored in 'value' and 
+		the call returns TIXML_SUCCESS. If it is not
+		an integer, it returns TIXML_WRONG_TYPE. If the attribute
+		does not exist, then TIXML_NO_ATTRIBUTE is returned.
+	*/	
+	int QueryIntAttribute( const char* name, int* _value ) const;
+	/// QueryUnsignedAttribute examines the attribute - see QueryIntAttribute().
+	int QueryUnsignedAttribute( const char* name, unsigned* _value ) const;
+	/** QueryBoolAttribute examines the attribute - see QueryIntAttribute(). 
+		Note that '1', 'true', or 'yes' are considered true, while '0', 'false'
+		and 'no' are considered false.
+	*/
+	int QueryBoolAttribute( const char* name, bool* _value ) const;
+	/// QueryDoubleAttribute examines the attribute - see QueryIntAttribute().
+	int QueryDoubleAttribute( const char* name, double* _value ) const;
+	/// QueryFloatAttribute examines the attribute - see QueryIntAttribute().
+	int QueryFloatAttribute( const char* name, float* _value ) const {
+		double d;
+		int result = QueryDoubleAttribute( name, &d );
+		if ( result == TIXML_SUCCESS ) {
+			*_value = (float)d;
+		}
+		return result;
+	}
+
+    #ifdef TIXML_USE_STL
+	/// QueryStringAttribute examines the attribute - see QueryIntAttribute().
+	int QueryStringAttribute( const char* name, std::string* _value ) const {
+		const char* cstr = Attribute( name );
+		if ( cstr ) {
+			*_value = std::string( cstr );
+			return TIXML_SUCCESS;
+		}
+		return TIXML_NO_ATTRIBUTE;
+	}
+
+	/** Template form of the attribute query which will try to read the
+		attribute into the specified type. Very easy, very powerful, but
+		be careful to make sure to call this with the correct type.
+		
+		NOTE: This method doesn't work correctly for 'string' types that contain spaces.
+
+		@return TIXML_SUCCESS, TIXML_WRONG_TYPE, or TIXML_NO_ATTRIBUTE
+	*/
+	template< typename T > int QueryValueAttribute( const std::string& name, T* outValue ) const
+	{
+		const TiXmlAttribute* node = attributeSet.Find( name );
+		if ( !node )
+			return TIXML_NO_ATTRIBUTE;
+
+		std::stringstream sstream( node->ValueStr() );
+		sstream >> *outValue;
+		if ( !sstream.fail() )
+			return TIXML_SUCCESS;
+		return TIXML_WRONG_TYPE;
+	}
+
+	int QueryValueAttribute( const std::string& name, std::string* outValue ) const
+	{
+		const TiXmlAttribute* node = attributeSet.Find( name );
+		if ( !node )
+			return TIXML_NO_ATTRIBUTE;
+		*outValue = node->ValueStr();
+		return TIXML_SUCCESS;
+	}
+	#endif
+
+	/** Sets an attribute of name to a given value. The attribute
+		will be created if it does not exist, or changed if it does.
+	*/
+	void SetAttribute( const char* name, const char * _value );
+
+    #ifdef TIXML_USE_STL
+	const std::string* Attribute( const std::string& name ) const;
+	const std::string* Attribute( const std::string& name, int* i ) const;
+	const std::string* Attribute( const std::string& name, double* d ) const;
+	int QueryIntAttribute( const std::string& name, int* _value ) const;
+	int QueryDoubleAttribute( const std::string& name, double* _value ) const;
+
+	/// STL std::string form.
+	void SetAttribute( const std::string& name, const std::string& _value );
+	///< STL std::string form.
+	void SetAttribute( const std::string& name, int _value );
+	///< STL std::string form.
+	void SetDoubleAttribute( const std::string& name, double value );
+	#endif
+
+	/** Sets an attribute of name to a given value. The attribute
+		will be created if it does not exist, or changed if it does.
+	*/
+	void SetAttribute( const char * name, int value );
+
+	/** Sets an attribute of name to a given value. The attribute
+		will be created if it does not exist, or changed if it does.
+	*/
+	void SetDoubleAttribute( const char * name, double value );
+
+	/** Deletes an attribute with the given name.
+	*/
+	void RemoveAttribute( const char * name );
+    #ifdef TIXML_USE_STL
+	void RemoveAttribute( const std::string& name )	{	RemoveAttribute (name.c_str ());	}	///< STL std::string form.
+	#endif
+
+	const TiXmlAttribute* FirstAttribute() const	{ return attributeSet.First(); }		///< Access the first attribute in this element.
+	TiXmlAttribute* FirstAttribute() 				{ return attributeSet.First(); }
+	const TiXmlAttribute* LastAttribute()	const 	{ return attributeSet.Last(); }		///< Access the last attribute in this element.
+	TiXmlAttribute* LastAttribute()					{ return attributeSet.Last(); }
+
+	/** Convenience function for easy access to the text inside an element. Although easy
+		and concise, GetText() is limited compared to getting the TiXmlText child
+		and accessing it directly.
+	
+		If the first child of 'this' is a TiXmlText, the GetText()
+		returns the character string of the Text node, else null is returned.
+
+		This is a convenient method for getting the text of simple contained text:
+		@verbatim
+		<foo>This is text</foo>
+		const char* str = fooElement->GetText();
+		@endverbatim
+
+		'str' will be a pointer to "This is text". 
+		
+		Note that this function can be misleading. If the element foo was created from
+		this XML:
+		@verbatim
+		<foo><b>This is text</b></foo> 
+		@endverbatim
+
+		then the value of str would be null. The first child node isn't a text node, it is
+		another element. From this XML:
+		@verbatim
+		<foo>This is <b>text</b></foo> 
+		@endverbatim
+		GetText() will return "This is ".
+
+		WARNING: GetText() accesses a child node - don't become confused with the 
+				 similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are 
+				 safe type casts on the referenced node.
+	*/
+	const char* GetText() const;
+
+	/// Creates a new Element and returns it - the returned element is a copy.
+	virtual TiXmlNode* Clone() const;
+	// Print the Element to a FILE stream.
+	virtual void Print( FILE* cfile, int depth ) const;
+
+	/*	Attribtue parsing starts: next char past '<'
+						 returns: next char past '>'
+	*/
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+	virtual const TiXmlElement*     ToElement()     const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+	virtual TiXmlElement*           ToElement()	          { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+	/** Walk the XML tree visiting this node and all of its children. 
+	*/
+	virtual bool Accept( TiXmlVisitor* visitor ) const;
+
+protected:
+
+	void CopyTo( TiXmlElement* target ) const;
+	void ClearThis();	// like clear, but initializes 'this' object as well
+
+	// Used to be public [internal use]
+	#ifdef TIXML_USE_STL
+	virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
+	#endif
+	/*	[internal use]
+		Reads the "value" of the element -- another element, or text.
+		This should terminate with the current end tag.
+	*/
+	const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding );
+
+private:
+	TiXmlAttributeSet attributeSet;
+};
+
+
+/**	An XML comment.
+*/
+class TiXmlComment : public TiXmlNode
+{
+public:
+	/// Constructs an empty comment.
+	TiXmlComment() : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) {}
+	/// Construct a comment from text.
+	TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) {
+		SetValue( _value );
+	}
+	TiXmlComment( const TiXmlComment& );
+	TiXmlComment& operator=( const TiXmlComment& base );
+
+	virtual ~TiXmlComment()	{}
+
+	/// Returns a copy of this Comment.
+	virtual TiXmlNode* Clone() const;
+	// Write this Comment to a FILE stream.
+	virtual void Print( FILE* cfile, int depth ) const;
+
+	/*	Attribtue parsing starts: at the ! of the !--
+						 returns: next char past '>'
+	*/
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+	virtual const TiXmlComment*  ToComment() const	{ return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+	virtual		  TiXmlComment*  ToComment()		{ return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+	/** Walk the XML tree visiting this node and all of its children. 
+	*/
+	virtual bool Accept( TiXmlVisitor* visitor ) const;
+
+protected:
+	void CopyTo( TiXmlComment* target ) const;
+
+	// used to be public
+	#ifdef TIXML_USE_STL
+	virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
+	#endif
+//	virtual void StreamOut( TIXML_OSTREAM * out ) const;
+
+private:
+
+};
+
+
+/** XML text. A text node can have 2 ways to output the next. "normal" output 
+	and CDATA. It will default to the mode it was parsed from the XML file and
+	you generally want to leave it alone, but you can change the output mode with 
+	SetCDATA() and query it with CDATA().
+*/
+class TiXmlText : public TiXmlNode
+{
+	friend class TiXmlElement;
+public:
+	/** Constructor for text element. By default, it is treated as 
+		normal, encoded text. If you want it be output as a CDATA text
+		element, set the parameter _cdata to 'true'
+	*/
+	TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT)
+	{
+		SetValue( initValue );
+		cdata = false;
+	}
+	virtual ~TiXmlText() {}
+
+	#ifdef TIXML_USE_STL
+	/// Constructor.
+	TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT)
+	{
+		SetValue( initValue );
+		cdata = false;
+	}
+	#endif
+
+	TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TINYXML_TEXT )	{ copy.CopyTo( this ); }
+	TiXmlText& operator=( const TiXmlText& base )							 	{ base.CopyTo( this ); return *this; }
+
+	// Write this text object to a FILE stream.
+	virtual void Print( FILE* cfile, int depth ) const;
+
+	/// Queries whether this represents text using a CDATA section.
+	bool CDATA() const				{ return cdata; }
+	/// Turns on or off a CDATA representation of text.
+	void SetCDATA( bool _cdata )	{ cdata = _cdata; }
+
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+	virtual const TiXmlText* ToText() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+	virtual TiXmlText*       ToText()       { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+	/** Walk the XML tree visiting this node and all of its children. 
+	*/
+	virtual bool Accept( TiXmlVisitor* content ) const;
+
+protected :
+	///  [internal use] Creates a new Element and returns it.
+	virtual TiXmlNode* Clone() const;
+	void CopyTo( TiXmlText* target ) const;
+
+	bool Blank() const;	// returns true if all white space and new lines
+	// [internal use]
+	#ifdef TIXML_USE_STL
+	virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
+	#endif
+
+private:
+	bool cdata;			// true if this should be input and output as a CDATA style text element
+};
+
+
+/** In correct XML the declaration is the first entry in the file.
+	@verbatim
+		<?xml version="1.0" standalone="yes"?>
+	@endverbatim
+
+	TinyXml will happily read or write files without a declaration,
+	however. There are 3 possible attributes to the declaration:
+	version, encoding, and standalone.
+
+	Note: In this version of the code, the attributes are
+	handled as special cases, not generic attributes, simply
+	because there can only be at most 3 and they are always the same.
+*/
+class TiXmlDeclaration : public TiXmlNode
+{
+public:
+	/// Construct an empty declaration.
+	TiXmlDeclaration()   : TiXmlNode( TiXmlNode::TINYXML_DECLARATION ) {}
+
+#ifdef TIXML_USE_STL
+	/// Constructor.
+	TiXmlDeclaration(	const std::string& _version,
+						const std::string& _encoding,
+						const std::string& _standalone );
+#endif
+
+	/// Construct.
+	TiXmlDeclaration(	const char* _version,
+						const char* _encoding,
+						const char* _standalone );
+
+	TiXmlDeclaration( const TiXmlDeclaration& copy );
+	TiXmlDeclaration& operator=( const TiXmlDeclaration& copy );
+
+	virtual ~TiXmlDeclaration()	{}
+
+	/// Version. Will return an empty string if none was found.
+	const char *Version() const			{ return version.c_str (); }
+	/// Encoding. Will return an empty string if none was found.
+	const char *Encoding() const		{ return encoding.c_str (); }
+	/// Is this a standalone document?
+	const char *Standalone() const		{ return standalone.c_str (); }
+
+	/// Creates a copy of this Declaration and returns it.
+	virtual TiXmlNode* Clone() const;
+	// Print this declaration to a FILE stream.
+	virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
+	virtual void Print( FILE* cfile, int depth ) const {
+		Print( cfile, depth, 0 );
+	}
+
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+	virtual const TiXmlDeclaration* ToDeclaration() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+	virtual TiXmlDeclaration*       ToDeclaration()       { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+	/** Walk the XML tree visiting this node and all of its children. 
+	*/
+	virtual bool Accept( TiXmlVisitor* visitor ) const;
+
+protected:
+	void CopyTo( TiXmlDeclaration* target ) const;
+	// used to be public
+	#ifdef TIXML_USE_STL
+	virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
+	#endif
+
+private:
+
+	TIXML_STRING version;
+	TIXML_STRING encoding;
+	TIXML_STRING standalone;
+};
+
+
+/** Any tag that tinyXml doesn't recognize is saved as an
+	unknown. It is a tag of text, but should not be modified.
+	It will be written back to the XML, unchanged, when the file
+	is saved.
+
+	DTD tags get thrown into TiXmlUnknowns.
+*/
+class TiXmlUnknown : public TiXmlNode
+{
+public:
+	TiXmlUnknown() : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN )	{}
+	virtual ~TiXmlUnknown() {}
+
+	TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN )		{ copy.CopyTo( this ); }
+	TiXmlUnknown& operator=( const TiXmlUnknown& copy )										{ copy.CopyTo( this ); return *this; }
+
+	/// Creates a copy of this Unknown and returns it.
+	virtual TiXmlNode* Clone() const;
+	// Print this Unknown to a FILE stream.
+	virtual void Print( FILE* cfile, int depth ) const;
+
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+	virtual const TiXmlUnknown*     ToUnknown()     const	{ return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+	virtual TiXmlUnknown*           ToUnknown()				{ return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+	/** Walk the XML tree visiting this node and all of its children. 
+	*/
+	virtual bool Accept( TiXmlVisitor* content ) const;
+
+protected:
+	void CopyTo( TiXmlUnknown* target ) const;
+
+	#ifdef TIXML_USE_STL
+	virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
+	#endif
+
+private:
+
+};
+
+
+/** Always the top level node. A document binds together all the
+	XML pieces. It can be saved, loaded, and printed to the screen.
+	The 'value' of a document node is the xml file name.
+*/
+class TiXmlDocument : public TiXmlNode
+{
+public:
+	/// Create an empty document, that has no name.
+	TiXmlDocument();
+	/// Create a document with a name. The name of the document is also the filename of the xml.
+	TiXmlDocument( const char * documentName );
+
+	#ifdef TIXML_USE_STL
+	/// Constructor.
+	TiXmlDocument( const std::string& documentName );
+	#endif
+
+	TiXmlDocument( const TiXmlDocument& copy );
+	TiXmlDocument& operator=( const TiXmlDocument& copy );
+
+	virtual ~TiXmlDocument() {}
+
+	/** Load a file using the current document value.
+		Returns true if successful. Will delete any existing
+		document data before loading.
+	*/
+	bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
+	/// Save a file using the current document value. Returns true if successful.
+	bool SaveFile() const;
+	/// Load a file using the given filename. Returns true if successful.
+	bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
+	/// Save a file using the given filename. Returns true if successful.
+	bool SaveFile( const char * filename ) const;
+	/** Load a file using the given FILE*. Returns true if successful. Note that this method
+		doesn't stream - the entire object pointed at by the FILE*
+		will be interpreted as an XML file. TinyXML doesn't stream in XML from the current
+		file location. Streaming may be added in the future.
+	*/
+	bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
+	/// Save a file using the given FILE*. Returns true if successful.
+	bool SaveFile( FILE* ) const;
+
+	#ifdef TIXML_USE_STL
+	bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING )			///< STL std::string version.
+	{
+		return LoadFile( filename.c_str(), encoding );
+	}
+	bool SaveFile( const std::string& filename ) const		///< STL std::string version.
+	{
+		return SaveFile( filename.c_str() );
+	}
+	#endif
+
+	/** Parse the given null terminated block of xml data. Passing in an encoding to this
+		method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml
+		to use that encoding, regardless of what TinyXml might otherwise try to detect.
+	*/
+	virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
+
+	/** Get the root element -- the only top level element -- of the document.
+		In well formed XML, there should only be one. TinyXml is tolerant of
+		multiple elements at the document level.
+	*/
+	const TiXmlElement* RootElement() const		{ return FirstChildElement(); }
+	TiXmlElement* RootElement()					{ return FirstChildElement(); }
+
+	/** If an error occurs, Error will be set to true. Also,
+		- The ErrorId() will contain the integer identifier of the error (not generally useful)
+		- The ErrorDesc() method will return the name of the error. (very useful)
+		- The ErrorRow() and ErrorCol() will return the location of the error (if known)
+	*/	
+	bool Error() const						{ return error; }
+
+	/// Contains a textual (english) description of the error if one occurs.
+	const char * ErrorDesc() const	{ return errorDesc.c_str (); }
+
+	/** Generally, you probably want the error string ( ErrorDesc() ). But if you
+		prefer the ErrorId, this function will fetch it.
+	*/
+	int ErrorId()	const				{ return errorId; }
+
+	/** Returns the location (if known) of the error. The first column is column 1, 
+		and the first row is row 1. A value of 0 means the row and column wasn't applicable
+		(memory errors, for example, have no row/column) or the parser lost the error. (An
+		error in the error reporting, in that case.)
+
+		@sa SetTabSize, Row, Column
+	*/
+	int ErrorRow() const	{ return errorLocation.row+1; }
+	int ErrorCol() const	{ return errorLocation.col+1; }	///< The column where the error occured. See ErrorRow()
+
+	/** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol())
+		to report the correct values for row and column. It does not change the output
+		or input in any way.
+		
+		By calling this method, with a tab size
+		greater than 0, the row and column of each node and attribute is stored
+		when the file is loaded. Very useful for tracking the DOM back in to
+		the source file.
+
+		The tab size is required for calculating the location of nodes. If not
+		set, the default of 4 is used. The tabsize is set per document. Setting
+		the tabsize to 0 disables row/column tracking.
+
+		Note that row and column tracking is not supported when using operator>>.
+
+		The tab size needs to be enabled before the parse or load. Correct usage:
+		@verbatim
+		TiXmlDocument doc;
+		doc.SetTabSize( 8 );
+		doc.Load( "myfile.xml" );
+		@endverbatim
+
+		@sa Row, Column
+	*/
+	void SetTabSize( int _tabsize )		{ tabsize = _tabsize; }
+
+	int TabSize() const	{ return tabsize; }
+
+	/** If you have handled the error, it can be reset with this call. The error
+		state is automatically cleared if you Parse a new XML block.
+	*/
+	void ClearError()						{	error = false; 
+												errorId = 0; 
+												errorDesc = ""; 
+												errorLocation.row = errorLocation.col = 0; 
+												//errorLocation.last = 0; 
+											}
+
+	/** Write the document to standard out using formatted printing ("pretty print"). */
+	void Print() const						{ Print( stdout, 0 ); }
+
+	/* Write the document to a string using formatted printing ("pretty print"). This
+		will allocate a character array (new char[]) and return it as a pointer. The
+		calling code pust call delete[] on the return char* to avoid a memory leak.
+	*/
+	//char* PrintToMemory() const; 
+
+	/// Print this Document to a FILE stream.
+	virtual void Print( FILE* cfile, int depth = 0 ) const;
+	// [internal use]
+	void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding );
+
+	virtual const TiXmlDocument*    ToDocument()    const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+	virtual TiXmlDocument*          ToDocument()          { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+	/** Walk the XML tree visiting this node and all of its children. 
+	*/
+	virtual bool Accept( TiXmlVisitor* content ) const;
+
+protected :
+	// [internal use]
+	virtual TiXmlNode* Clone() const;
+	#ifdef TIXML_USE_STL
+	virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
+	#endif
+
+private:
+	void CopyTo( TiXmlDocument* target ) const;
+
+	bool error;
+	int  errorId;
+	TIXML_STRING errorDesc;
+	int tabsize;
+	TiXmlCursor errorLocation;
+	bool useMicrosoftBOM;		// the UTF-8 BOM were found when read. Note this, and try to write.
+};
+
+
+/**
+	A TiXmlHandle is a class that wraps a node pointer with null checks; this is
+	an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml
+	DOM structure. It is a separate utility class.
+
+	Take an example:
+	@verbatim
+	<Document>
+		<Element attributeA = "valueA">
+			<Child attributeB = "value1" />
+			<Child attributeB = "value2" />
+		</Element>
+	<Document>
+	@endverbatim
+
+	Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very 
+	easy to write a *lot* of code that looks like:
+
+	@verbatim
+	TiXmlElement* root = document.FirstChildElement( "Document" );
+	if ( root )
+	{
+		TiXmlElement* element = root->FirstChildElement( "Element" );
+		if ( element )
+		{
+			TiXmlElement* child = element->FirstChildElement( "Child" );
+			if ( child )
+			{
+				TiXmlElement* child2 = child->NextSiblingElement( "Child" );
+				if ( child2 )
+				{
+					// Finally do something useful.
+	@endverbatim
+
+	And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity
+	of such code. A TiXmlHandle checks for null	pointers so it is perfectly safe 
+	and correct to use:
+
+	@verbatim
+	TiXmlHandle docHandle( &document );
+	TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement();
+	if ( child2 )
+	{
+		// do something useful
+	@endverbatim
+
+	Which is MUCH more concise and useful.
+
+	It is also safe to copy handles - internally they are nothing more than node pointers.
+	@verbatim
+	TiXmlHandle handleCopy = handle;
+	@endverbatim
+
+	What they should not be used for is iteration:
+
+	@verbatim
+	int i=0; 
+	while ( true )
+	{
+		TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).ToElement();
+		if ( !child )
+			break;
+		// do something
+		++i;
+	}
+	@endverbatim
+
+	It seems reasonable, but it is in fact two embedded while loops. The Child method is 
+	a linear walk to find the element, so this code would iterate much more than it needs 
+	to. Instead, prefer:
+
+	@verbatim
+	TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).ToElement();
+
+	for( child; child; child=child->NextSiblingElement() )
+	{
+		// do something
+	}
+	@endverbatim
+*/
+class TiXmlHandle
+{
+public:
+	/// Create a handle from any node (at any depth of the tree.) This can be a null pointer.
+	TiXmlHandle( TiXmlNode* _node )					{ this->node = _node; }
+	/// Copy constructor
+	TiXmlHandle( const TiXmlHandle& ref )			{ this->node = ref.node; }
+	TiXmlHandle operator=( const TiXmlHandle& ref ) { if ( &ref != this ) this->node = ref.node; return *this; }
+
+	/// Return a handle to the first child node.
+	TiXmlHandle FirstChild() const;
+	/// Return a handle to the first child node with the given name.
+	TiXmlHandle FirstChild( const char * value ) const;
+	/// Return a handle to the first child element.
+	TiXmlHandle FirstChildElement() const;
+	/// Return a handle to the first child element with the given name.
+	TiXmlHandle FirstChildElement( const char * value ) const;
+
+	/** Return a handle to the "index" child with the given name. 
+		The first child is 0, the second 1, etc.
+	*/
+	TiXmlHandle Child( const char* value, int index ) const;
+	/** Return a handle to the "index" child. 
+		The first child is 0, the second 1, etc.
+	*/
+	TiXmlHandle Child( int index ) const;
+	/** Return a handle to the "index" child element with the given name. 
+		The first child element is 0, the second 1, etc. Note that only TiXmlElements
+		are indexed: other types are not counted.
+	*/
+	TiXmlHandle ChildElement( const char* value, int index ) const;
+	/** Return a handle to the "index" child element. 
+		The first child element is 0, the second 1, etc. Note that only TiXmlElements
+		are indexed: other types are not counted.
+	*/
+	TiXmlHandle ChildElement( int index ) const;
+
+	#ifdef TIXML_USE_STL
+	TiXmlHandle FirstChild( const std::string& _value ) const				{ return FirstChild( _value.c_str() ); }
+	TiXmlHandle FirstChildElement( const std::string& _value ) const		{ return FirstChildElement( _value.c_str() ); }
+
+	TiXmlHandle Child( const std::string& _value, int index ) const			{ return Child( _value.c_str(), index ); }
+	TiXmlHandle ChildElement( const std::string& _value, int index ) const	{ return ChildElement( _value.c_str(), index ); }
+	#endif
+
+	/** Return the handle as a TiXmlNode. This may return null.
+	*/
+	TiXmlNode* ToNode() const			{ return node; } 
+	/** Return the handle as a TiXmlElement. This may return null.
+	*/
+	TiXmlElement* ToElement() const		{ return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); }
+	/**	Return the handle as a TiXmlText. This may return null.
+	*/
+	TiXmlText* ToText() const			{ return ( ( node && node->ToText() ) ? node->ToText() : 0 ); }
+	/** Return the handle as a TiXmlUnknown. This may return null.
+	*/
+	TiXmlUnknown* ToUnknown() const		{ return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); }
+
+	/** @deprecated use ToNode. 
+		Return the handle as a TiXmlNode. This may return null.
+	*/
+	TiXmlNode* Node() const			{ return ToNode(); } 
+	/** @deprecated use ToElement. 
+		Return the handle as a TiXmlElement. This may return null.
+	*/
+	TiXmlElement* Element() const	{ return ToElement(); }
+	/**	@deprecated use ToText()
+		Return the handle as a TiXmlText. This may return null.
+	*/
+	TiXmlText* Text() const			{ return ToText(); }
+	/** @deprecated use ToUnknown()
+		Return the handle as a TiXmlUnknown. This may return null.
+	*/
+	TiXmlUnknown* Unknown() const	{ return ToUnknown(); }
+
+private:
+	TiXmlNode* node;
+};
+
+
+/** Print to memory functionality. The TiXmlPrinter is useful when you need to:
+
+	-# Print to memory (especially in non-STL mode)
+	-# Control formatting (line endings, etc.)
+
+	When constructed, the TiXmlPrinter is in its default "pretty printing" mode.
+	Before calling Accept() you can call methods to control the printing
+	of the XML document. After TiXmlNode::Accept() is called, the printed document can
+	be accessed via the CStr(), Str(), and Size() methods.
+
+	TiXmlPrinter uses the Visitor API.
+	@verbatim
+	TiXmlPrinter printer;
+	printer.SetIndent( "\t" );
+
+	doc.Accept( &printer );
+	fprintf( stdout, "%s", printer.CStr() );
+	@endverbatim
+*/
+class TiXmlPrinter : public TiXmlVisitor
+{
+public:
+	TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ),
+					 buffer(), indent( "    " ), lineBreak( "\n" ) {}
+
+	virtual bool VisitEnter( const TiXmlDocument& doc );
+	virtual bool VisitExit( const TiXmlDocument& doc );
+
+	virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute );
+	virtual bool VisitExit( const TiXmlElement& element );
+
+	virtual bool Visit( const TiXmlDeclaration& declaration );
+	virtual bool Visit( const TiXmlText& text );
+	virtual bool Visit( const TiXmlComment& comment );
+	virtual bool Visit( const TiXmlUnknown& unknown );
+
+	/** Set the indent characters for printing. By default 4 spaces
+		but tab (\t) is also useful, or null/empty string for no indentation.
+	*/
+	void SetIndent( const char* _indent )			{ indent = _indent ? _indent : "" ; }
+	/// Query the indention string.
+	const char* Indent()							{ return indent.c_str(); }
+	/** Set the line breaking string. By default set to newline (\n). 
+		Some operating systems prefer other characters, or can be
+		set to the null/empty string for no indenation.
+	*/
+	void SetLineBreak( const char* _lineBreak )		{ lineBreak = _lineBreak ? _lineBreak : ""; }
+	/// Query the current line breaking string.
+	const char* LineBreak()							{ return lineBreak.c_str(); }
+
+	/** Switch over to "stream printing" which is the most dense formatting without 
+		linebreaks. Common when the XML is needed for network transmission.
+	*/
+	void SetStreamPrinting()						{ indent = "";
+													  lineBreak = "";
+													}	
+	/// Return the result.
+	const char* CStr()								{ return buffer.c_str(); }
+	/// Return the length of the result string.
+	size_t Size()									{ return buffer.size(); }
+
+	#ifdef TIXML_USE_STL
+	/// Return the result.
+	const std::string& Str()						{ return buffer; }
+	#endif
+
+private:
+	void DoIndent()	{
+		for( int i=0; i<depth; ++i )
+			buffer += indent;
+	}
+	void DoLineBreak() {
+		buffer += lineBreak;
+	}
+
+	int depth;
+	bool simpleTextPrint;
+	TIXML_STRING buffer;
+	TIXML_STRING indent;
+	TIXML_STRING lineBreak;
+};
+
+
+#ifdef _MSC_VER
+#pragma warning( pop )
+#endif
+
+#endif
diff --git a/test/tinyxml/tinyxmlerror.cpp b/test/tinyxml/tinyxmlerror.cpp
new file mode 100644
index 0000000..538c21d
--- /dev/null
+++ b/test/tinyxml/tinyxmlerror.cpp
@@ -0,0 +1,52 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com)
+
+This software is provided 'as-is', without any express or implied 
+warranty. In no event will the authors be held liable for any 
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any 
+purpose, including commercial applications, and to alter it and 
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+*/
+
+#include "tinyxml.h"
+
+// The goal of the seperate error file is to make the first
+// step towards localization. tinyxml (currently) only supports
+// english error messages, but the could now be translated.
+//
+// It also cleans up the code a bit.
+//
+
+const char* TiXmlBase::errorString[ TiXmlBase::TIXML_ERROR_STRING_COUNT ] =
+{
+	"No error",
+	"Error",
+	"Failed to open file",
+	"Error parsing Element.",
+	"Failed to read Element name",
+	"Error reading Element value.",
+	"Error reading Attributes.",
+	"Error: empty tag.",
+	"Error reading end tag.",
+	"Error parsing Unknown.",
+	"Error parsing Comment.",
+	"Error parsing Declaration.",
+	"Error document empty.",
+	"Error null (0) or unexpected EOF found in input stream.",
+	"Error parsing CDATA.",
+	"Error when TiXmlDocument added to document, because TiXmlDocument can only be at the root.",
+};
diff --git a/test/tinyxml/tinyxmlparser.cpp b/test/tinyxml/tinyxmlparser.cpp
new file mode 100644
index 0000000..81b7eae
--- /dev/null
+++ b/test/tinyxml/tinyxmlparser.cpp
@@ -0,0 +1,1638 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original code by Lee Thomason (www.grinninglizard.com)
+
+This software is provided 'as-is', without any express or implied 
+warranty. In no event will the authors be held liable for any 
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any 
+purpose, including commercial applications, and to alter it and 
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must 
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and 
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source 
+distribution.
+*/
+
+#include <ctype.h>
+#include <stddef.h>
+
+#include "tinyxml.h"
+
+//#define DEBUG_PARSER
+#if defined( DEBUG_PARSER )
+#	if defined( DEBUG ) && defined( _MSC_VER )
+#		include <windows.h>
+#		define TIXML_LOG OutputDebugString
+#	else
+#		define TIXML_LOG printf
+#	endif
+#endif
+
+// Note tha "PutString" hardcodes the same list. This
+// is less flexible than it appears. Changing the entries
+// or order will break putstring.	
+TiXmlBase::Entity TiXmlBase::entity[ TiXmlBase::NUM_ENTITY ] = 
+{
+	{ "&amp;",  5, '&' },
+	{ "&lt;",   4, '<' },
+	{ "&gt;",   4, '>' },
+	{ "&quot;", 6, '\"' },
+	{ "&apos;", 6, '\'' }
+};
+
+// Bunch of unicode info at:
+//		http://www.unicode.org/faq/utf_bom.html
+// Including the basic of this table, which determines the #bytes in the
+// sequence from the lead byte. 1 placed for invalid sequences --
+// although the result will be junk, pass it through as much as possible.
+// Beware of the non-characters in UTF-8:	
+//				ef bb bf (Microsoft "lead bytes")
+//				ef bf be
+//				ef bf bf 
+
+const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
+const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
+const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
+
+const int TiXmlBase::utf8ByteTable[256] = 
+{
+	//	0	1	2	3	4	5	6	7	8	9	a	b	c	d	e	f
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x00
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x10
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x20
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x30
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x40
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x50
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x60
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x70	End of ASCII range
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x80 0x80 to 0xc1 invalid
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x90 
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0xa0 
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0xb0 
+		1,	1,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	// 0xc0 0xc2 to 0xdf 2 byte
+		2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	// 0xd0
+		3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	// 0xe0 0xe0 to 0xef 3 byte
+		4,	4,	4,	4,	4,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1	// 0xf0 0xf0 to 0xf4 4 byte, 0xf5 and higher invalid
+};
+
+
+void TiXmlBase::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length )
+{
+	const unsigned long BYTE_MASK = 0xBF;
+	const unsigned long BYTE_MARK = 0x80;
+	const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+
+	if (input < 0x80) 
+		*length = 1;
+	else if ( input < 0x800 )
+		*length = 2;
+	else if ( input < 0x10000 )
+		*length = 3;
+	else if ( input < 0x200000 )
+		*length = 4;
+	else
+		{ *length = 0; return; }	// This code won't covert this correctly anyway.
+
+	output += *length;
+
+	// Scary scary fall throughs.
+	switch (*length) 
+	{
+		case 4:
+			--output; 
+			*output = (char)((input | BYTE_MARK) & BYTE_MASK); 
+			input >>= 6;
+		case 3:
+			--output; 
+			*output = (char)((input | BYTE_MARK) & BYTE_MASK); 
+			input >>= 6;
+		case 2:
+			--output; 
+			*output = (char)((input | BYTE_MARK) & BYTE_MASK); 
+			input >>= 6;
+		case 1:
+			--output; 
+			*output = (char)(input | FIRST_BYTE_MARK[*length]);
+	}
+}
+
+
+/*static*/ int TiXmlBase::IsAlpha( unsigned char anyByte, TiXmlEncoding /*encoding*/ )
+{
+	// This will only work for low-ascii, everything else is assumed to be a valid
+	// letter. I'm not sure this is the best approach, but it is quite tricky trying
+	// to figure out alhabetical vs. not across encoding. So take a very 
+	// conservative approach.
+
+//	if ( encoding == TIXML_ENCODING_UTF8 )
+//	{
+		if ( anyByte < 127 )
+			return isalpha( anyByte );
+		else
+			return 1;	// What else to do? The unicode set is huge...get the english ones right.
+//	}
+//	else
+//	{
+//		return isalpha( anyByte );
+//	}
+}
+
+
+/*static*/ int TiXmlBase::IsAlphaNum( unsigned char anyByte, TiXmlEncoding /*encoding*/ )
+{
+	// This will only work for low-ascii, everything else is assumed to be a valid
+	// letter. I'm not sure this is the best approach, but it is quite tricky trying
+	// to figure out alhabetical vs. not across encoding. So take a very 
+	// conservative approach.
+
+//	if ( encoding == TIXML_ENCODING_UTF8 )
+//	{
+		if ( anyByte < 127 )
+			return isalnum( anyByte );
+		else
+			return 1;	// What else to do? The unicode set is huge...get the english ones right.
+//	}
+//	else
+//	{
+//		return isalnum( anyByte );
+//	}
+}
+
+
+class TiXmlParsingData
+{
+	friend class TiXmlDocument;
+  public:
+	void Stamp( const char* now, TiXmlEncoding encoding );
+
+	const TiXmlCursor& Cursor() const	{ return cursor; }
+
+  private:
+	// Only used by the document!
+	TiXmlParsingData( const char* start, int _tabsize, int row, int col )
+	{
+		assert( start );
+		stamp = start;
+		tabsize = _tabsize;
+		cursor.row = row;
+		cursor.col = col;
+	}
+
+	TiXmlCursor		cursor;
+	const char*		stamp;
+	int				tabsize;
+};
+
+
+void TiXmlParsingData::Stamp( const char* now, TiXmlEncoding encoding )
+{
+	assert( now );
+
+	// Do nothing if the tabsize is 0.
+	if ( tabsize < 1 )
+	{
+		return;
+	}
+
+	// Get the current row, column.
+	int row = cursor.row;
+	int col = cursor.col;
+	const char* p = stamp;
+	assert( p );
+
+	while ( p < now )
+	{
+		// Treat p as unsigned, so we have a happy compiler.
+		const unsigned char* pU = (const unsigned char*)p;
+
+		// Code contributed by Fletcher Dunn: (modified by lee)
+		switch (*pU) {
+			case 0:
+				// We *should* never get here, but in case we do, don't
+				// advance past the terminating null character, ever
+				return;
+
+			case '\r':
+				// bump down to the next line
+				++row;
+				col = 0;				
+				// Eat the character
+				++p;
+
+				// Check for \r\n sequence, and treat this as a single character
+				if (*p == '\n') {
+					++p;
+				}
+				break;
+
+			case '\n':
+				// bump down to the next line
+				++row;
+				col = 0;
+
+				// Eat the character
+				++p;
+
+				// Check for \n\r sequence, and treat this as a single
+				// character.  (Yes, this bizarre thing does occur still
+				// on some arcane platforms...)
+				if (*p == '\r') {
+					++p;
+				}
+				break;
+
+			case '\t':
+				// Eat the character
+				++p;
+
+				// Skip to next tab stop
+				col = (col / tabsize + 1) * tabsize;
+				break;
+
+			case TIXML_UTF_LEAD_0:
+				if ( encoding == TIXML_ENCODING_UTF8 )
+				{
+					if ( *(p+1) && *(p+2) )
+					{
+						// In these cases, don't advance the column. These are
+						// 0-width spaces.
+						if ( *(pU+1)==TIXML_UTF_LEAD_1 && *(pU+2)==TIXML_UTF_LEAD_2 )
+							p += 3;	
+						else if ( *(pU+1)==0xbfU && *(pU+2)==0xbeU )
+							p += 3;	
+						else if ( *(pU+1)==0xbfU && *(pU+2)==0xbfU )
+							p += 3;	
+						else
+							{ p +=3; ++col; }	// A normal character.
+					}
+				}
+				else
+				{
+					++p;
+					++col;
+				}
+				break;
+
+			default:
+				if ( encoding == TIXML_ENCODING_UTF8 )
+				{
+					// Eat the 1 to 4 byte utf8 character.
+					int step = TiXmlBase::utf8ByteTable[*((const unsigned char*)p)];
+					if ( step == 0 )
+						step = 1;		// Error case from bad encoding, but handle gracefully.
+					p += step;
+
+					// Just advance one column, of course.
+					++col;
+				}
+				else
+				{
+					++p;
+					++col;
+				}
+				break;
+		}
+	}
+	cursor.row = row;
+	cursor.col = col;
+	assert( cursor.row >= -1 );
+	assert( cursor.col >= -1 );
+	stamp = p;
+	assert( stamp );
+}
+
+
+const char* TiXmlBase::SkipWhiteSpace( const char* p, TiXmlEncoding encoding )
+{
+	if ( !p || !*p )
+	{
+		return 0;
+	}
+	if ( encoding == TIXML_ENCODING_UTF8 )
+	{
+		while ( *p )
+		{
+			const unsigned char* pU = (const unsigned char*)p;
+			
+			// Skip the stupid Microsoft UTF-8 Byte order marks
+			if (	*(pU+0)==TIXML_UTF_LEAD_0
+				 && *(pU+1)==TIXML_UTF_LEAD_1 
+				 && *(pU+2)==TIXML_UTF_LEAD_2 )
+			{
+				p += 3;
+				continue;
+			}
+			else if(*(pU+0)==TIXML_UTF_LEAD_0
+				 && *(pU+1)==0xbfU
+				 && *(pU+2)==0xbeU )
+			{
+				p += 3;
+				continue;
+			}
+			else if(*(pU+0)==TIXML_UTF_LEAD_0
+				 && *(pU+1)==0xbfU
+				 && *(pU+2)==0xbfU )
+			{
+				p += 3;
+				continue;
+			}
+
+			if ( IsWhiteSpace( *p ) )		// Still using old rules for white space.
+				++p;
+			else
+				break;
+		}
+	}
+	else
+	{
+		while ( *p && IsWhiteSpace( *p ) )
+			++p;
+	}
+
+	return p;
+}
+
+#ifdef TIXML_USE_STL
+/*static*/ bool TiXmlBase::StreamWhiteSpace( std::istream * in, TIXML_STRING * tag )
+{
+	for( ;; )
+	{
+		if ( !in->good() ) return false;
+
+		int c = in->peek();
+		// At this scope, we can't get to a document. So fail silently.
+		if ( !IsWhiteSpace( c ) || c <= 0 )
+			return true;
+
+		*tag += (char) in->get();
+	}
+}
+
+/*static*/ bool TiXmlBase::StreamTo( std::istream * in, int character, TIXML_STRING * tag )
+{
+	//assert( character > 0 && character < 128 );	// else it won't work in utf-8
+	while ( in->good() )
+	{
+		int c = in->peek();
+		if ( c == character )
+			return true;
+		if ( c <= 0 )		// Silent failure: can't get document at this scope
+			return false;
+
+		in->get();
+		*tag += (char) c;
+	}
+	return false;
+}
+#endif
+
+// One of TinyXML's more performance demanding functions. Try to keep the memory overhead down. The
+// "assign" optimization removes over 10% of the execution time.
+//
+const char* TiXmlBase::ReadName( const char* p, TIXML_STRING * name, TiXmlEncoding encoding )
+{
+	// Oddly, not supported on some comilers,
+	//name->clear();
+	// So use this:
+	*name = "";
+	assert( p );
+
+	// Names start with letters or underscores.
+	// Of course, in unicode, tinyxml has no idea what a letter *is*. The
+	// algorithm is generous.
+	//
+	// After that, they can be letters, underscores, numbers,
+	// hyphens, or colons. (Colons are valid ony for namespaces,
+	// but tinyxml can't tell namespaces from names.)
+	if (    p && *p 
+		 && ( IsAlpha( (unsigned char) *p, encoding ) || *p == '_' ) )
+	{
+		const char* start = p;
+		while(		p && *p
+				&&	(		IsAlphaNum( (unsigned char ) *p, encoding ) 
+						 || *p == '_'
+						 || *p == '-'
+						 || *p == '.'
+						 || *p == ':' ) )
+		{
+			//(*name) += *p; // expensive
+			++p;
+		}
+		if ( p-start > 0 ) {
+			name->assign( start, p-start );
+		}
+		return p;
+	}
+	return 0;
+}
+
+const char* TiXmlBase::GetEntity( const char* p, char* value, int* length, TiXmlEncoding encoding )
+{
+	// Presume an entity, and pull it out.
+    TIXML_STRING ent;
+	int i;
+	*length = 0;
+
+	if ( *(p+1) && *(p+1) == '#' && *(p+2) )
+	{
+		unsigned long ucs = 0;
+		ptrdiff_t delta = 0;
+		unsigned mult = 1;
+
+		if ( *(p+2) == 'x' )
+		{
+			// Hexadecimal.
+			if ( !*(p+3) ) return 0;
+
+			const char* q = p+3;
+			q = strchr( q, ';' );
+
+			if ( !q || !*q ) return 0;
+
+			delta = q-p;
+			--q;
+
+			while ( *q != 'x' )
+			{
+				if ( *q >= '0' && *q <= '9' )
+					ucs += mult * (*q - '0');
+				else if ( *q >= 'a' && *q <= 'f' )
+					ucs += mult * (*q - 'a' + 10);
+				else if ( *q >= 'A' && *q <= 'F' )
+					ucs += mult * (*q - 'A' + 10 );
+				else 
+					return 0;
+				mult *= 16;
+				--q;
+			}
+		}
+		else
+		{
+			// Decimal.
+			if ( !*(p+2) ) return 0;
+
+			const char* q = p+2;
+			q = strchr( q, ';' );
+
+			if ( !q || !*q ) return 0;
+
+			delta = q-p;
+			--q;
+
+			while ( *q != '#' )
+			{
+				if ( *q >= '0' && *q <= '9' )
+					ucs += mult * (*q - '0');
+				else 
+					return 0;
+				mult *= 10;
+				--q;
+			}
+		}
+		if ( encoding == TIXML_ENCODING_UTF8 )
+		{
+			// convert the UCS to UTF-8
+			ConvertUTF32ToUTF8( ucs, value, length );
+		}
+		else
+		{
+			*value = (char)ucs;
+			*length = 1;
+		}
+		return p + delta + 1;
+	}
+
+	// Now try to match it.
+	for( i=0; i<NUM_ENTITY; ++i )
+	{
+		if ( strncmp( entity[i].str, p, entity[i].strLength ) == 0 )
+		{
+			assert( strlen( entity[i].str ) == entity[i].strLength );
+			*value = entity[i].chr;
+			*length = 1;
+			return ( p + entity[i].strLength );
+		}
+	}
+
+	// So it wasn't an entity, its unrecognized, or something like that.
+	*value = *p;	// Don't put back the last one, since we return it!
+	//*length = 1;	// Leave unrecognized entities - this doesn't really work.
+					// Just writes strange XML.
+	return p+1;
+}
+
+
+bool TiXmlBase::StringEqual( const char* p,
+							 const char* tag,
+							 bool ignoreCase,
+							 TiXmlEncoding encoding )
+{
+	assert( p );
+	assert( tag );
+	if ( !p || !*p )
+	{
+		assert( 0 );
+		return false;
+	}
+
+	const char* q = p;
+
+	if ( ignoreCase )
+	{
+		while ( *q && *tag && ToLower( *q, encoding ) == ToLower( *tag, encoding ) )
+		{
+			++q;
+			++tag;
+		}
+
+		if ( *tag == 0 )
+			return true;
+	}
+	else
+	{
+		while ( *q && *tag && *q == *tag )
+		{
+			++q;
+			++tag;
+		}
+
+		if ( *tag == 0 )		// Have we found the end of the tag, and everything equal?
+			return true;
+	}
+	return false;
+}
+
+const char* TiXmlBase::ReadText(	const char* p, 
+									TIXML_STRING * text, 
+									bool trimWhiteSpace, 
+									const char* endTag, 
+									bool caseInsensitive,
+									TiXmlEncoding encoding )
+{
+    *text = "";
+	if (    !trimWhiteSpace			// certain tags always keep whitespace
+		 || !condenseWhiteSpace )	// if true, whitespace is always kept
+	{
+		// Keep all the white space.
+		while (	   p && *p
+				&& !StringEqual( p, endTag, caseInsensitive, encoding )
+			  )
+		{
+			int len;
+			char cArr[4] = { 0, 0, 0, 0 };
+			p = GetChar( p, cArr, &len, encoding );
+			text->append( cArr, len );
+		}
+	}
+	else
+	{
+		bool whitespace = false;
+
+		// Remove leading white space:
+		p = SkipWhiteSpace( p, encoding );
+		while (	   p && *p
+				&& !StringEqual( p, endTag, caseInsensitive, encoding ) )
+		{
+			if ( *p == '\r' || *p == '\n' )
+			{
+				whitespace = true;
+				++p;
+			}
+			else if ( IsWhiteSpace( *p ) )
+			{
+				whitespace = true;
+				++p;
+			}
+			else
+			{
+				// If we've found whitespace, add it before the
+				// new character. Any whitespace just becomes a space.
+				if ( whitespace )
+				{
+					(*text) += ' ';
+					whitespace = false;
+				}
+				int len;
+				char cArr[4] = { 0, 0, 0, 0 };
+				p = GetChar( p, cArr, &len, encoding );
+				if ( len == 1 )
+					(*text) += cArr[0];	// more efficient
+				else
+					text->append( cArr, len );
+			}
+		}
+	}
+	if ( p && *p )
+		p += strlen( endTag );
+	return ( p && *p ) ? p : 0;
+}
+
+#ifdef TIXML_USE_STL
+
+void TiXmlDocument::StreamIn( std::istream * in, TIXML_STRING * tag )
+{
+	// The basic issue with a document is that we don't know what we're
+	// streaming. Read something presumed to be a tag (and hope), then
+	// identify it, and call the appropriate stream method on the tag.
+	//
+	// This "pre-streaming" will never read the closing ">" so the
+	// sub-tag can orient itself.
+
+	if ( !StreamTo( in, '<', tag ) ) 
+	{
+		SetError( TIXML_ERROR_PARSING_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return;
+	}
+
+	while ( in->good() )
+	{
+		int tagIndex = (int) tag->length();
+		while ( in->good() && in->peek() != '>' )
+		{
+			int c = in->get();
+			if ( c <= 0 )
+			{
+				SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+				break;
+			}
+			(*tag) += (char) c;
+		}
+
+		if ( in->good() )
+		{
+			// We now have something we presume to be a node of 
+			// some sort. Identify it, and call the node to
+			// continue streaming.
+			TiXmlNode* node = Identify( tag->c_str() + tagIndex, TIXML_DEFAULT_ENCODING );
+
+			if ( node )
+			{
+				node->StreamIn( in, tag );
+				bool isElement = node->ToElement() != 0;
+				delete node;
+				node = 0;
+
+				// If this is the root element, we're done. Parsing will be
+				// done by the >> operator.
+				if ( isElement )
+				{
+					return;
+				}
+			}
+			else
+			{
+				SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN );
+				return;
+			}
+		}
+	}
+	// We should have returned sooner.
+	SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN );
+}
+
+#endif
+
+const char* TiXmlDocument::Parse( const char* p, TiXmlParsingData* prevData, TiXmlEncoding encoding )
+{
+	ClearError();
+
+	// Parse away, at the document level. Since a document
+	// contains nothing but other tags, most of what happens
+	// here is skipping white space.
+	if ( !p || !*p )
+	{
+		SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return 0;
+	}
+
+	// Note that, for a document, this needs to come
+	// before the while space skip, so that parsing
+	// starts from the pointer we are given.
+	location.Clear();
+	if ( prevData )
+	{
+		location.row = prevData->cursor.row;
+		location.col = prevData->cursor.col;
+	}
+	else
+	{
+		location.row = 0;
+		location.col = 0;
+	}
+	TiXmlParsingData data( p, TabSize(), location.row, location.col );
+	location = data.Cursor();
+
+	if ( encoding == TIXML_ENCODING_UNKNOWN )
+	{
+		// Check for the Microsoft UTF-8 lead bytes.
+		const unsigned char* pU = (const unsigned char*)p;
+		if (	*(pU+0) && *(pU+0) == TIXML_UTF_LEAD_0
+			 && *(pU+1) && *(pU+1) == TIXML_UTF_LEAD_1
+			 && *(pU+2) && *(pU+2) == TIXML_UTF_LEAD_2 )
+		{
+			encoding = TIXML_ENCODING_UTF8;
+			useMicrosoftBOM = true;
+		}
+	}
+
+    p = SkipWhiteSpace( p, encoding );
+	if ( !p )
+	{
+		SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return 0;
+	}
+
+	while ( p && *p )
+	{
+		TiXmlNode* node = Identify( p, encoding );
+		if ( node )
+		{
+			p = node->Parse( p, &data, encoding );
+			LinkEndChild( node );
+		}
+		else
+		{
+			break;
+		}
+
+		// Did we get encoding info?
+		if (    encoding == TIXML_ENCODING_UNKNOWN
+			 && node->ToDeclaration() )
+		{
+			TiXmlDeclaration* dec = node->ToDeclaration();
+			const char* enc = dec->Encoding();
+			assert( enc );
+
+			if ( *enc == 0 )
+				encoding = TIXML_ENCODING_UTF8;
+			else if ( StringEqual( enc, "UTF-8", true, TIXML_ENCODING_UNKNOWN ) )
+				encoding = TIXML_ENCODING_UTF8;
+			else if ( StringEqual( enc, "UTF8", true, TIXML_ENCODING_UNKNOWN ) )
+				encoding = TIXML_ENCODING_UTF8;	// incorrect, but be nice
+			else 
+				encoding = TIXML_ENCODING_LEGACY;
+		}
+
+		p = SkipWhiteSpace( p, encoding );
+	}
+
+	// Was this empty?
+	if ( !firstChild ) {
+		SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, encoding );
+		return 0;
+	}
+
+	// All is well.
+	return p;
+}
+
+void TiXmlDocument::SetError( int err, const char* pError, TiXmlParsingData* data, TiXmlEncoding encoding )
+{	
+	// The first error in a chain is more accurate - don't set again!
+	if ( error )
+		return;
+
+	assert( err > 0 && err < TIXML_ERROR_STRING_COUNT );
+	error   = true;
+	errorId = err;
+	errorDesc = errorString[ errorId ];
+
+	errorLocation.Clear();
+	if ( pError && data )
+	{
+		data->Stamp( pError, encoding );
+		errorLocation = data->Cursor();
+	}
+}
+
+
+TiXmlNode* TiXmlNode::Identify( const char* p, TiXmlEncoding encoding )
+{
+	TiXmlNode* returnNode = 0;
+
+	p = SkipWhiteSpace( p, encoding );
+	if( !p || !*p || *p != '<' )
+	{
+		return 0;
+	}
+
+	p = SkipWhiteSpace( p, encoding );
+
+	if ( !p || !*p )
+	{
+		return 0;
+	}
+
+	// What is this thing? 
+	// - Elements start with a letter or underscore, but xml is reserved.
+	// - Comments: <!--
+	// - Decleration: <?xml
+	// - Everthing else is unknown to tinyxml.
+	//
+
+	const char* xmlHeader = { "<?xml" };
+	const char* commentHeader = { "<!--" };
+	const char* dtdHeader = { "<!" };
+	const char* cdataHeader = { "<![CDATA[" };
+
+	if ( StringEqual( p, xmlHeader, true, encoding ) )
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing Declaration\n" );
+		#endif
+		returnNode = new TiXmlDeclaration();
+	}
+	else if ( StringEqual( p, commentHeader, false, encoding ) )
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing Comment\n" );
+		#endif
+		returnNode = new TiXmlComment();
+	}
+	else if ( StringEqual( p, cdataHeader, false, encoding ) )
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing CDATA\n" );
+		#endif
+		TiXmlText* text = new TiXmlText( "" );
+		text->SetCDATA( true );
+		returnNode = text;
+	}
+	else if ( StringEqual( p, dtdHeader, false, encoding ) )
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing Unknown(1)\n" );
+		#endif
+		returnNode = new TiXmlUnknown();
+	}
+	else if (    IsAlpha( *(p+1), encoding )
+			  || *(p+1) == '_' )
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing Element\n" );
+		#endif
+		returnNode = new TiXmlElement( "" );
+	}
+	else
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing Unknown(2)\n" );
+		#endif
+		returnNode = new TiXmlUnknown();
+	}
+
+	if ( returnNode )
+	{
+		// Set the parent, so it can report errors
+		returnNode->parent = this;
+	}
+	return returnNode;
+}
+
+#ifdef TIXML_USE_STL
+
+void TiXmlElement::StreamIn (std::istream * in, TIXML_STRING * tag)
+{
+	// We're called with some amount of pre-parsing. That is, some of "this"
+	// element is in "tag". Go ahead and stream to the closing ">"
+	while( in->good() )
+	{
+		int c = in->get();
+		if ( c <= 0 )
+		{
+			TiXmlDocument* document = GetDocument();
+			if ( document )
+				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+			return;
+		}
+		(*tag) += (char) c ;
+		
+		if ( c == '>' )
+			break;
+	}
+
+	if ( tag->length() < 3 ) return;
+
+	// Okay...if we are a "/>" tag, then we're done. We've read a complete tag.
+	// If not, identify and stream.
+
+	if (    tag->at( tag->length() - 1 ) == '>' 
+		 && tag->at( tag->length() - 2 ) == '/' )
+	{
+		// All good!
+		return;
+	}
+	else if ( tag->at( tag->length() - 1 ) == '>' )
+	{
+		// There is more. Could be:
+		//		text
+		//		cdata text (which looks like another node)
+		//		closing tag
+		//		another node.
+		for ( ;; )
+		{
+			StreamWhiteSpace( in, tag );
+
+			// Do we have text?
+			if ( in->good() && in->peek() != '<' ) 
+			{
+				// Yep, text.
+				TiXmlText text( "" );
+				text.StreamIn( in, tag );
+
+				// What follows text is a closing tag or another node.
+				// Go around again and figure it out.
+				continue;
+			}
+
+			// We now have either a closing tag...or another node.
+			// We should be at a "<", regardless.
+			if ( !in->good() ) return;
+			assert( in->peek() == '<' );
+			int tagIndex = (int) tag->length();
+
+			bool closingTag = false;
+			bool firstCharFound = false;
+
+			for( ;; )
+			{
+				if ( !in->good() )
+					return;
+
+				int c = in->peek();
+				if ( c <= 0 )
+				{
+					TiXmlDocument* document = GetDocument();
+					if ( document )
+						document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+					return;
+				}
+				
+				if ( c == '>' )
+					break;
+
+				*tag += (char) c;
+				in->get();
+
+				// Early out if we find the CDATA id.
+				if ( c == '[' && tag->size() >= 9 )
+				{
+					size_t len = tag->size();
+					const char* start = tag->c_str() + len - 9;
+					if ( strcmp( start, "<![CDATA[" ) == 0 ) {
+						assert( !closingTag );
+						break;
+					}
+				}
+
+				if ( !firstCharFound && c != '<' && !IsWhiteSpace( c ) )
+				{
+					firstCharFound = true;
+					if ( c == '/' )
+						closingTag = true;
+				}
+			}
+			// If it was a closing tag, then read in the closing '>' to clean up the input stream.
+			// If it was not, the streaming will be done by the tag.
+			if ( closingTag )
+			{
+				if ( !in->good() )
+					return;
+
+				int c = in->get();
+				if ( c <= 0 )
+				{
+					TiXmlDocument* document = GetDocument();
+					if ( document )
+						document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+					return;
+				}
+				assert( c == '>' );
+				*tag += (char) c;
+
+				// We are done, once we've found our closing tag.
+				return;
+			}
+			else
+			{
+				// If not a closing tag, id it, and stream.
+				const char* tagloc = tag->c_str() + tagIndex;
+				TiXmlNode* node = Identify( tagloc, TIXML_DEFAULT_ENCODING );
+				if ( !node )
+					return;
+				node->StreamIn( in, tag );
+				delete node;
+				node = 0;
+
+				// No return: go around from the beginning: text, closing tag, or node.
+			}
+		}
+	}
+}
+#endif
+
+const char* TiXmlElement::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	p = SkipWhiteSpace( p, encoding );
+	TiXmlDocument* document = GetDocument();
+
+	if ( !p || !*p )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, 0, 0, encoding );
+		return 0;
+	}
+
+	if ( data )
+	{
+		data->Stamp( p, encoding );
+		location = data->Cursor();
+	}
+
+	if ( *p != '<' )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, p, data, encoding );
+		return 0;
+	}
+
+	p = SkipWhiteSpace( p+1, encoding );
+
+	// Read the name.
+	const char* pErr = p;
+
+    p = ReadName( p, &value, encoding );
+	if ( !p || !*p )
+	{
+		if ( document )	document->SetError( TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, pErr, data, encoding );
+		return 0;
+	}
+
+    TIXML_STRING endTag ("</");
+	endTag += value;
+
+	// Check for and read attributes. Also look for an empty
+	// tag or an end tag.
+	while ( p && *p )
+	{
+		pErr = p;
+		p = SkipWhiteSpace( p, encoding );
+		if ( !p || !*p )
+		{
+			if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding );
+			return 0;
+		}
+		if ( *p == '/' )
+		{
+			++p;
+			// Empty tag.
+			if ( *p  != '>' )
+			{
+				if ( document ) document->SetError( TIXML_ERROR_PARSING_EMPTY, p, data, encoding );		
+				return 0;
+			}
+			return (p+1);
+		}
+		else if ( *p == '>' )
+		{
+			// Done with attributes (if there were any.)
+			// Read the value -- which can include other
+			// elements -- read the end tag, and return.
+			++p;
+			p = ReadValue( p, data, encoding );		// Note this is an Element method, and will set the error if one happens.
+			if ( !p || !*p ) {
+				// We were looking for the end tag, but found nothing.
+				// Fix for [ 1663758 ] Failure to report error on bad XML
+				if ( document ) document->SetError( TIXML_ERROR_READING_END_TAG, p, data, encoding );
+				return 0;
+			}
+
+			// We should find the end tag now
+			// note that:
+			// </foo > and
+			// </foo> 
+			// are both valid end tags.
+			if ( StringEqual( p, endTag.c_str(), false, encoding ) )
+			{
+				p += endTag.length();
+				p = SkipWhiteSpace( p, encoding );
+				if ( p && *p && *p == '>' ) {
+					++p;
+					return p;
+				}
+				if ( document ) document->SetError( TIXML_ERROR_READING_END_TAG, p, data, encoding );
+				return 0;
+			}
+			else
+			{
+				if ( document ) document->SetError( TIXML_ERROR_READING_END_TAG, p, data, encoding );
+				return 0;
+			}
+		}
+		else
+		{
+			// Try to read an attribute:
+			TiXmlAttribute* attrib = new TiXmlAttribute();
+			if ( !attrib )
+			{
+				return 0;
+			}
+
+			attrib->SetDocument( document );
+			pErr = p;
+			p = attrib->Parse( p, data, encoding );
+
+			if ( !p || !*p )
+			{
+				if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, pErr, data, encoding );
+				delete attrib;
+				return 0;
+			}
+
+			// Handle the strange case of double attributes:
+			#ifdef TIXML_USE_STL
+			TiXmlAttribute* node = attributeSet.Find( attrib->NameTStr() );
+			#else
+			TiXmlAttribute* node = attributeSet.Find( attrib->Name() );
+			#endif
+			if ( node )
+			{
+				if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, pErr, data, encoding );
+				delete attrib;
+				return 0;
+			}
+
+			attributeSet.Add( attrib );
+		}
+	}
+	return p;
+}
+
+
+const char* TiXmlElement::ReadValue( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	TiXmlDocument* document = GetDocument();
+
+	// Read in text and elements in any order.
+	const char* pWithWhiteSpace = p;
+	p = SkipWhiteSpace( p, encoding );
+
+	while ( p && *p )
+	{
+		if ( *p != '<' )
+		{
+			// Take what we have, make a text element.
+			TiXmlText* textNode = new TiXmlText( "" );
+
+			if ( !textNode )
+			{
+			    return 0;
+			}
+
+			if ( TiXmlBase::IsWhiteSpaceCondensed() )
+			{
+				p = textNode->Parse( p, data, encoding );
+			}
+			else
+			{
+				// Special case: we want to keep the white space
+				// so that leading spaces aren't removed.
+				p = textNode->Parse( pWithWhiteSpace, data, encoding );
+			}
+
+			if ( !textNode->Blank() )
+				LinkEndChild( textNode );
+			else
+				delete textNode;
+		} 
+		else 
+		{
+			// We hit a '<'
+			// Have we hit a new element or an end tag? This could also be
+			// a TiXmlText in the "CDATA" style.
+			if ( StringEqual( p, "</", false, encoding ) )
+			{
+				return p;
+			}
+			else
+			{
+				TiXmlNode* node = Identify( p, encoding );
+				if ( node )
+				{
+					p = node->Parse( p, data, encoding );
+					LinkEndChild( node );
+				}				
+				else
+				{
+					return 0;
+				}
+			}
+		}
+		pWithWhiteSpace = p;
+		p = SkipWhiteSpace( p, encoding );
+	}
+
+	if ( !p )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_READING_ELEMENT_VALUE, 0, 0, encoding );
+	}	
+	return p;
+}
+
+
+#ifdef TIXML_USE_STL
+void TiXmlUnknown::StreamIn( std::istream * in, TIXML_STRING * tag )
+{
+	while ( in->good() )
+	{
+		int c = in->get();	
+		if ( c <= 0 )
+		{
+			TiXmlDocument* document = GetDocument();
+			if ( document )
+				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+			return;
+		}
+		(*tag) += (char) c;
+
+		if ( c == '>' )
+		{
+			// All is well.
+			return;		
+		}
+	}
+}
+#endif
+
+
+const char* TiXmlUnknown::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	TiXmlDocument* document = GetDocument();
+	p = SkipWhiteSpace( p, encoding );
+
+	if ( data )
+	{
+		data->Stamp( p, encoding );
+		location = data->Cursor();
+	}
+	if ( !p || !*p || *p != '<' )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_PARSING_UNKNOWN, p, data, encoding );
+		return 0;
+	}
+	++p;
+    value = "";
+
+	while ( p && *p && *p != '>' )
+	{
+		value += *p;
+		++p;
+	}
+
+	if ( !p )
+	{
+		if ( document )	
+			document->SetError( TIXML_ERROR_PARSING_UNKNOWN, 0, 0, encoding );
+	}
+	if ( p && *p == '>' )
+		return p+1;
+	return p;
+}
+
+#ifdef TIXML_USE_STL
+void TiXmlComment::StreamIn( std::istream * in, TIXML_STRING * tag )
+{
+	while ( in->good() )
+	{
+		int c = in->get();	
+		if ( c <= 0 )
+		{
+			TiXmlDocument* document = GetDocument();
+			if ( document )
+				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+			return;
+		}
+
+		(*tag) += (char) c;
+
+		if ( c == '>' 
+			 && tag->at( tag->length() - 2 ) == '-'
+			 && tag->at( tag->length() - 3 ) == '-' )
+		{
+			// All is well.
+			return;		
+		}
+	}
+}
+#endif
+
+
+const char* TiXmlComment::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	TiXmlDocument* document = GetDocument();
+	value = "";
+
+	p = SkipWhiteSpace( p, encoding );
+
+	if ( data )
+	{
+		data->Stamp( p, encoding );
+		location = data->Cursor();
+	}
+	const char* startTag = "<!--";
+	const char* endTag   = "-->";
+
+	if ( !StringEqual( p, startTag, false, encoding ) )
+	{
+		if ( document )
+			document->SetError( TIXML_ERROR_PARSING_COMMENT, p, data, encoding );
+		return 0;
+	}
+	p += strlen( startTag );
+
+	// [ 1475201 ] TinyXML parses entities in comments
+	// Oops - ReadText doesn't work, because we don't want to parse the entities.
+	// p = ReadText( p, &value, false, endTag, false, encoding );
+	//
+	// from the XML spec:
+	/*
+	 [Definition: Comments may appear anywhere in a document outside other markup; in addition, 
+	              they may appear within the document type declaration at places allowed by the grammar. 
+				  They are not part of the document's character data; an XML processor MAY, but need not, 
+				  make it possible for an application to retrieve the text of comments. For compatibility, 
+				  the string "--" (double-hyphen) MUST NOT occur within comments.] Parameter entity 
+				  references MUST NOT be recognized within comments.
+
+				  An example of a comment:
+
+				  <!-- declarations for <head> & <body> -->
+	*/
+
+    value = "";
+	// Keep all the white space.
+	while (	p && *p && !StringEqual( p, endTag, false, encoding ) )
+	{
+		value.append( p, 1 );
+		++p;
+	}
+	if ( p && *p ) 
+		p += strlen( endTag );
+
+	return p;
+}
+
+
+const char* TiXmlAttribute::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	p = SkipWhiteSpace( p, encoding );
+	if ( !p || !*p ) return 0;
+
+	if ( data )
+	{
+		data->Stamp( p, encoding );
+		location = data->Cursor();
+	}
+	// Read the name, the '=' and the value.
+	const char* pErr = p;
+	p = ReadName( p, &name, encoding );
+	if ( !p || !*p )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding );
+		return 0;
+	}
+	p = SkipWhiteSpace( p, encoding );
+	if ( !p || !*p || *p != '=' )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding );
+		return 0;
+	}
+
+	++p;	// skip '='
+	p = SkipWhiteSpace( p, encoding );
+	if ( !p || !*p )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding );
+		return 0;
+	}
+	
+	const char* end;
+	const char SINGLE_QUOTE = '\'';
+	const char DOUBLE_QUOTE = '\"';
+
+	if ( *p == SINGLE_QUOTE )
+	{
+		++p;
+		end = "\'";		// single quote in string
+		p = ReadText( p, &value, false, end, false, encoding );
+	}
+	else if ( *p == DOUBLE_QUOTE )
+	{
+		++p;
+		end = "\"";		// double quote in string
+		p = ReadText( p, &value, false, end, false, encoding );
+	}
+	else
+	{
+		// All attribute values should be in single or double quotes.
+		// But this is such a common error that the parser will try
+		// its best, even without them.
+		value = "";
+		while (    p && *p											// existence
+				&& !IsWhiteSpace( *p )								// whitespace
+				&& *p != '/' && *p != '>' )							// tag end
+		{
+			if ( *p == SINGLE_QUOTE || *p == DOUBLE_QUOTE ) {
+				// [ 1451649 ] Attribute values with trailing quotes not handled correctly
+				// We did not have an opening quote but seem to have a 
+				// closing one. Give up and throw an error.
+				if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding );
+				return 0;
+			}
+			value += *p;
+			++p;
+		}
+	}
+	return p;
+}
+
+#ifdef TIXML_USE_STL
+void TiXmlText::StreamIn( std::istream * in, TIXML_STRING * tag )
+{
+	while ( in->good() )
+	{
+		int c = in->peek();	
+		if ( !cdata && (c == '<' ) ) 
+		{
+			return;
+		}
+		if ( c <= 0 )
+		{
+			TiXmlDocument* document = GetDocument();
+			if ( document )
+				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+			return;
+		}
+
+		(*tag) += (char) c;
+		in->get();	// "commits" the peek made above
+
+		if ( cdata && c == '>' && tag->size() >= 3 ) {
+			size_t len = tag->size();
+			if ( (*tag)[len-2] == ']' && (*tag)[len-3] == ']' ) {
+				// terminator of cdata.
+				return;
+			}
+		}    
+	}
+}
+#endif
+
+const char* TiXmlText::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	value = "";
+	TiXmlDocument* document = GetDocument();
+
+	if ( data )
+	{
+		data->Stamp( p, encoding );
+		location = data->Cursor();
+	}
+
+	const char* const startTag = "<![CDATA[";
+	const char* const endTag   = "]]>";
+
+	if ( cdata || StringEqual( p, startTag, false, encoding ) )
+	{
+		cdata = true;
+
+		if ( !StringEqual( p, startTag, false, encoding ) )
+		{
+			if ( document )
+				document->SetError( TIXML_ERROR_PARSING_CDATA, p, data, encoding );
+			return 0;
+		}
+		p += strlen( startTag );
+
+		// Keep all the white space, ignore the encoding, etc.
+		while (	   p && *p
+				&& !StringEqual( p, endTag, false, encoding )
+			  )
+		{
+			value += *p;
+			++p;
+		}
+
+		TIXML_STRING dummy; 
+		p = ReadText( p, &dummy, false, endTag, false, encoding );
+		return p;
+	}
+	else
+	{
+		bool ignoreWhite = true;
+
+		const char* end = "<";
+		p = ReadText( p, &value, ignoreWhite, end, false, encoding );
+		if ( p && *p )
+			return p-1;	// don't truncate the '<'
+		return 0;
+	}
+}
+
+#ifdef TIXML_USE_STL
+void TiXmlDeclaration::StreamIn( std::istream * in, TIXML_STRING * tag )
+{
+	while ( in->good() )
+	{
+		int c = in->get();
+		if ( c <= 0 )
+		{
+			TiXmlDocument* document = GetDocument();
+			if ( document )
+				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+			return;
+		}
+		(*tag) += (char) c;
+
+		if ( c == '>' )
+		{
+			// All is well.
+			return;
+		}
+	}
+}
+#endif
+
+const char* TiXmlDeclaration::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding _encoding )
+{
+	p = SkipWhiteSpace( p, _encoding );
+	// Find the beginning, find the end, and look for
+	// the stuff in-between.
+	TiXmlDocument* document = GetDocument();
+	if ( !p || !*p || !StringEqual( p, "<?xml", true, _encoding ) )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_PARSING_DECLARATION, 0, 0, _encoding );
+		return 0;
+	}
+	if ( data )
+	{
+		data->Stamp( p, _encoding );
+		location = data->Cursor();
+	}
+	p += 5;
+
+	version = "";
+	encoding = "";
+	standalone = "";
+
+	while ( p && *p )
+	{
+		if ( *p == '>' )
+		{
+			++p;
+			return p;
+		}
+
+		p = SkipWhiteSpace( p, _encoding );
+		if ( StringEqual( p, "version", true, _encoding ) )
+		{
+			TiXmlAttribute attrib;
+			p = attrib.Parse( p, data, _encoding );		
+			version = attrib.Value();
+		}
+		else if ( StringEqual( p, "encoding", true, _encoding ) )
+		{
+			TiXmlAttribute attrib;
+			p = attrib.Parse( p, data, _encoding );		
+			encoding = attrib.Value();
+		}
+		else if ( StringEqual( p, "standalone", true, _encoding ) )
+		{
+			TiXmlAttribute attrib;
+			p = attrib.Parse( p, data, _encoding );		
+			standalone = attrib.Value();
+		}
+		else
+		{
+			// Read over whatever it is.
+			while( p && *p && *p != '>' && !IsWhiteSpace( *p ) )
+				++p;
+		}
+	}
+	return 0;
+}
+
+bool TiXmlText::Blank() const
+{
+	for ( unsigned i=0; i<value.length(); i++ )
+		if ( !IsWhiteSpace( value[i] ) )
+			return false;
+	return true;
+}
+
diff --git a/test/verify_glyf.cc b/test/verify_glyf.cc
new file mode 100644
index 0000000..abfe1ab
--- /dev/null
+++ b/test/verify_glyf.cc
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "gtest/gtest.h"
+#include "sfntly/font.h"
+#include "sfntly/table/truetype/glyph_table.h"
+#include "test/serialization_test.h"
+
+namespace sfntly {
+
+// We spot check only glyph id 33.
+const int32_t GLYPH33_OFFSET = 0xAC8;
+const int32_t GLYPH33_LENGTH = 40;
+const int32_t GLYPH33_XMIN = 92;
+const int32_t GLYPH33_YMIN = 20;
+const int32_t GLYPH33_XMAX = 797;
+const int32_t GLYPH33_YMAX = 1235;
+
+// TODO(arthurhsu): Tuffy does not have composite glyphs.  Need better testing.
+static bool VerifyGLYF(Table* table) {
+  GlyphTablePtr glyf_table = down_cast<GlyphTable*>(table);
+  if (glyf_table == NULL) {
+    return false;
+  }
+
+  GlyphPtr glyf;
+  glyf.Attach(glyf_table->GetGlyph(GLYPH33_OFFSET, GLYPH33_LENGTH));
+  if (glyf == NULL) {
+    return false;
+  }
+
+  EXPECT_EQ(glyf->XMin(), GLYPH33_XMIN);
+  EXPECT_EQ(glyf->YMin(), GLYPH33_YMIN);
+  EXPECT_EQ(glyf->XMax(), GLYPH33_XMAX);
+  EXPECT_EQ(glyf->YMax(), GLYPH33_YMAX);
+
+  return true;
+}
+
+bool VerifyGLYF(Table* original, Table* target) {
+  EXPECT_TRUE(VerifyGLYF(original));
+  EXPECT_TRUE(VerifyGLYF(target));
+  return true;
+}
+
+}  // namespace sfntly
diff --git a/test/verify_hhea.cc b/test/verify_hhea.cc
new file mode 100644
index 0000000..81ddb58
--- /dev/null
+++ b/test/verify_hhea.cc
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "gtest/gtest.h"
+#include "sfntly/font.h"
+#include "sfntly/math/fixed1616.h"
+#include "sfntly/table/core/horizontal_header_table.h"
+#include "test/serialization_test.h"
+
+namespace sfntly {
+
+const int32_t HHEA_ASCENDER = 2023;
+const int32_t HHEA_DESCENDER = -648;
+const int32_t HHEA_LINE_GAP = 93;
+const int32_t HHEA_ADVANCE_WIDTH_MAX = 2753;
+const int32_t HHEA_MIN_LSB = -968;
+const int32_t HHEA_MIN_RSB = -411;
+const int32_t HHEA_X_MAX_EXTENT = 2628;
+const int32_t HHEA_METRIC_DATA_FORMAT = 0;
+const int32_t HHEA_NUM_METRICS = 1499;
+
+static bool VerifyHHEA(Table* table) {
+  HorizontalHeaderTablePtr hhea = down_cast<HorizontalHeaderTable*>(table);
+  if (hhea == NULL) {
+    return false;
+  }
+
+  EXPECT_EQ(hhea->TableVersion(), Fixed1616::Fixed(1, 0));
+  EXPECT_EQ(hhea->Ascender(), HHEA_ASCENDER);
+  EXPECT_EQ(hhea->Descender(), HHEA_DESCENDER);
+  EXPECT_EQ(hhea->AdvanceWidthMax(), HHEA_ADVANCE_WIDTH_MAX);
+  EXPECT_EQ(hhea->MinLeftSideBearing(), HHEA_MIN_LSB);
+  EXPECT_EQ(hhea->MinRightSideBearing(), HHEA_MIN_RSB);
+  EXPECT_EQ(hhea->XMaxExtent(), HHEA_X_MAX_EXTENT);
+  // TODO(arthurhsu): CaretSlopeRise() not tested
+  // TODO(arthurhsu): CaretSlopeRun() not tested
+  // TODO(arthurhsu): CaretOffset() not tested
+  EXPECT_EQ(hhea->MetricDataFormat(), HHEA_METRIC_DATA_FORMAT);
+  EXPECT_EQ(hhea->NumberOfHMetrics(), HHEA_NUM_METRICS);
+
+  return true;
+}
+
+bool VerifyHHEA(Table* original, Table* target) {
+  EXPECT_TRUE(VerifyHHEA(original));
+  EXPECT_TRUE(VerifyHHEA(target));
+  return true;
+}
+
+}  // namespace sfntly
diff --git a/test/verify_hmtx.cc b/test/verify_hmtx.cc
new file mode 100644
index 0000000..d37bba9
--- /dev/null
+++ b/test/verify_hmtx.cc
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "gtest/gtest.h"
+#include "sfntly/font.h"
+#include "sfntly/table/core/horizontal_metrics_table.h"
+#include "test/serialization_test.h"
+
+namespace sfntly {
+
+const int32_t HMTX_ENTRIES_COUNT = 1499;
+const int32_t HMTX_LSB_COUNT = 3;
+
+struct HmtxEntry {
+  int32_t advance_width_;
+  int32_t lsb_;
+
+  HmtxEntry(int32_t advance_width, int32_t lsb)
+      : advance_width_(advance_width), lsb_(lsb) {}
+};
+
+const HmtxEntry HMTX_ENTRIES[] = {
+    HmtxEntry(748, 68),  // 0
+    HmtxEntry(0, 0),  // 1
+    HmtxEntry(682, 0),  // 2
+    HmtxEntry(616, 0),  // 3
+    HmtxEntry(421, 103),  // 4
+    HmtxEntry(690, 129),  // 5
+    HmtxEntry(1589, 129),  // 6
+    HmtxEntry(1017, 25),  // 7
+    HmtxEntry(1402, 104),  // 8
+    HmtxEntry(1241, 100),  // 9
+};
+const int32_t NUM_HMTX_ENTRIES = 10;
+
+static bool VerifyHMTX(Table* table) {
+  HorizontalMetricsTablePtr hmtx = down_cast<HorizontalMetricsTable*>(table);
+  if (hmtx == NULL) {
+    return false;
+  }
+
+  EXPECT_EQ(hmtx->NumberOfHMetrics(), HMTX_ENTRIES_COUNT);
+  EXPECT_EQ(hmtx->NumberOfLSBs(), HMTX_LSB_COUNT);
+
+  for (int32_t i = 0; i < NUM_HMTX_ENTRIES; ++i) {
+    EXPECT_EQ(hmtx->AdvanceWidth(i), HMTX_ENTRIES[i].advance_width_);
+    EXPECT_EQ(hmtx->LeftSideBearing(i), HMTX_ENTRIES[i].lsb_);
+  }
+
+  // No such element case.
+  EXPECT_EQ(hmtx->AdvanceWidth(HMTX_ENTRIES_COUNT),
+            HMTX_ENTRIES[0].advance_width_);
+  EXPECT_EQ(hmtx->LeftSideBearing(HMTX_ENTRIES_COUNT), HMTX_ENTRIES[0].lsb_);
+  return true;
+}
+
+bool VerifyHMTX(Table* original, Table* target) {
+  EXPECT_TRUE(VerifyHMTX(original));
+  EXPECT_TRUE(VerifyHMTX(target));
+  return true;
+}
+
+}  // namespace sfntly
diff --git a/test/verify_loca.cc b/test/verify_loca.cc
new file mode 100644
index 0000000..4a32928
--- /dev/null
+++ b/test/verify_loca.cc
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "gtest/gtest.h"
+#include "sfntly/font.h"
+#include "sfntly/table/truetype/loca_table.h"
+#include "test/serialization_test.h"
+
+namespace sfntly {
+
+const int32_t LOCA_NUM_LOCAS = 1503;
+const int32_t LOCAS[] = {
+    0x00000,  // 0
+    0x00058,  // 1
+    0x00058,  // 2
+    0x00058,  // 3
+    0x00058,  // 4
+    0x000B8,  // 5
+    0x00138,  // 6
+    0x001A4,  // 7
+    0x0025C,  // 8
+    0x00328,  // 9
+    0x003B8,  // 10
+};
+const int32_t NUM_TEST_LOCAS = 11;
+
+static bool VerifyLOCA(Table* table) {
+  LocaTablePtr loca = down_cast<LocaTable*>(table);
+  if (loca == NULL) {
+    return false;
+  }
+
+  EXPECT_EQ(loca->NumLocas(), LOCA_NUM_LOCAS);
+  EXPECT_EQ(loca->num_glyphs(), LOCA_NUM_LOCAS - 1);
+
+  for (int32_t i = 0; i < NUM_TEST_LOCAS - 1; ++i) {
+    EXPECT_EQ(loca->GlyphOffset(i), LOCAS[i]);
+    EXPECT_EQ(loca->GlyphLength(i), LOCAS[i + 1] - LOCAS[i]);
+  }
+  return true;
+}
+
+bool VerifyLOCA(Table* original, Table* target) {
+  EXPECT_TRUE(VerifyLOCA(original));
+  EXPECT_TRUE(VerifyLOCA(target));
+  return true;
+}
+
+}  // namespace sfntly
diff --git a/test/verify_maxp.cc b/test/verify_maxp.cc
new file mode 100644
index 0000000..dcd776e
--- /dev/null
+++ b/test/verify_maxp.cc
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "gtest/gtest.h"
+#include "sfntly/font.h"
+#include "sfntly/math/fixed1616.h"
+#include "sfntly/table/core/maximum_profile_table.h"
+#include "test/serialization_test.h"
+
+namespace sfntly {
+
+const int32_t MAXP_NUM_GLYPHS = 1502;
+const int32_t MAXP_MAX_POINTS = 181;
+const int32_t MAXP_MAX_CONTOURS = 9;
+const int32_t MAXP_MAX_COMPOSITE_POINTS = 172;
+const int32_t MAXP_MAX_COMPOSITE_CONTOURS = 5;
+const int32_t MAXP_MAX_ZONES = 2;
+const int32_t MAXP_MAX_TWILIGHT_POINTS = 0;
+const int32_t MAXP_MAX_STORAGE = 1;
+const int32_t MAXP_MAX_FUNCTION_DEFS = 1;
+const int32_t MAXP_MAX_INSTR_DEFS = 0;
+const int32_t MAXP_MAX_STACK_ELEMENTS = 64;
+const int32_t MAXP_MAX_INSTR_SIZE = 46;
+const int32_t MAXP_MAX_COMPONENT_ELEMENTS = 4;
+const int32_t MAXP_MAX_COMPONENT_DEPTH = 3;
+
+static bool VerifyMAXP(Table* table) {
+  MaximumProfileTablePtr maxp = down_cast<MaximumProfileTable*>(table);
+  if (maxp == NULL) {
+    return false;
+  }
+
+  EXPECT_EQ(maxp->TableVersion(), Fixed1616::Fixed(1, 0));
+  EXPECT_EQ(maxp->NumGlyphs(), MAXP_NUM_GLYPHS);
+  EXPECT_EQ(maxp->MaxPoints(), MAXP_MAX_POINTS);
+  EXPECT_EQ(maxp->MaxContours(), MAXP_MAX_CONTOURS);
+  EXPECT_EQ(maxp->MaxCompositePoints(), MAXP_MAX_COMPOSITE_POINTS);
+  EXPECT_EQ(maxp->MaxCompositeContours(), MAXP_MAX_COMPOSITE_CONTOURS);
+  EXPECT_EQ(maxp->MaxZones(), MAXP_MAX_ZONES);
+  EXPECT_EQ(maxp->MaxTwilightPoints(), MAXP_MAX_TWILIGHT_POINTS);
+  EXPECT_EQ(maxp->MaxStorage(), MAXP_MAX_STORAGE);
+  EXPECT_EQ(maxp->MaxFunctionDefs(), MAXP_MAX_FUNCTION_DEFS);
+  // TODO(arthurhsu): maxInstructionDefs observed in Microsoft TTF report.
+  //                  Check with stuartg and see if this is a miss.
+  EXPECT_EQ(maxp->MaxStackElements(), MAXP_MAX_STACK_ELEMENTS);
+  EXPECT_EQ(maxp->MaxSizeOfInstructions(), MAXP_MAX_INSTR_SIZE);
+  EXPECT_EQ(maxp->MaxComponentElements(), MAXP_MAX_COMPONENT_ELEMENTS);
+  EXPECT_EQ(maxp->MaxComponentDepth(), MAXP_MAX_COMPONENT_DEPTH);
+
+  return true;
+}
+
+bool VerifyMAXP(Table* original, Table* target) {
+  EXPECT_TRUE(VerifyMAXP(original));
+  EXPECT_TRUE(VerifyMAXP(target));
+  return true;
+}
+
+}  // namespace sfntly
diff --git a/test/verify_name.cc b/test/verify_name.cc
new file mode 100644
index 0000000..e1101c0
--- /dev/null
+++ b/test/verify_name.cc
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "gtest/gtest.h"
+#include "sfntly/font.h"
+#include "sfntly/table/core/name_table.h"
+#include "test/serialization_test.h"
+
+namespace sfntly {
+
+const int32_t NAME_FORMAT = 0;
+const int32_t NAME_COUNT = 75;
+const NameTable::NameEntryId NAME_IDS[] = {
+    NameTable::NameEntryId(1, 0, 0, 0),  // 0
+    NameTable::NameEntryId(1, 0, 0, 1),  // 1
+    NameTable::NameEntryId(1, 0, 0, 2),  // 2
+    NameTable::NameEntryId(1, 0, 0, 3),  // 3
+    NameTable::NameEntryId(1, 0, 0, 4),  // 4
+    NameTable::NameEntryId(1, 0, 0, 5),  // 5
+    NameTable::NameEntryId(1, 0, 0, 6),  // 6
+    NameTable::NameEntryId(1, 0, 0, 9),  // 7
+    NameTable::NameEntryId(1, 0, 0, 11),  // 8
+    NameTable::NameEntryId(1, 0, 0, 12),  // 9
+};
+const int32_t NAME_IDS_TEST = 10;
+
+static bool VerifyNAME(Table* table) {
+  // TODO(arthurhsu): Better testing can be done here.  Right now we just
+  //                  iterate through the entries and get entry ids.
+  NameTablePtr name = down_cast<NameTable*>(table);
+  if (name == NULL) {
+    return false;
+  }
+
+  EXPECT_EQ(name->Format(), NAME_FORMAT);
+  EXPECT_EQ(name->NameCount(), NAME_COUNT);
+  fprintf(stderr, "checking name entry: ");
+  for (int32_t i = 0; i < NAME_IDS_TEST; ++i) {
+    fprintf(stderr, "%d ", i);
+    EXPECT_EQ(name->PlatformId(i), NAME_IDS[i].platform_id());
+    EXPECT_EQ(name->EncodingId(i), NAME_IDS[i].encoding_id());
+    EXPECT_EQ(name->LanguageId(i), NAME_IDS[i].language_id());
+    EXPECT_EQ(name->NameId(i), NAME_IDS[i].name_id());
+  }
+  fprintf(stderr, "\n");
+  return true;
+}
+
+bool VerifyNAME(Table* original, Table* target) {
+  EXPECT_TRUE(VerifyNAME(original));
+  EXPECT_TRUE(VerifyNAME(target));
+  return true;
+}
+
+}  // namespace sfntly
diff --git a/test/verify_os2.cc b/test/verify_os2.cc
new file mode 100644
index 0000000..4897e87
--- /dev/null
+++ b/test/verify_os2.cc
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "gtest/gtest.h"
+#include "sfntly/font.h"
+#include "sfntly/table/core/os2_table.h"
+#include "test/serialization_test.h"
+
+namespace sfntly {
+
+const int32_t OS2_VERSION = 1;
+const int32_t OS2_XAVG_CHAR_WIDTH = 863;
+const int32_t OS2_US_WEIGHT_CLASS = 500;
+const int32_t OS2_US_WIDTH_CLASS = 5;
+const int32_t OS2_FS_TYPE = 0;
+const int32_t OS2_YSUBS_XSIZE = 0;
+const int32_t OS2_YSUBS_YSIZE = 2;
+const int32_t OS2_YSUBS_XOFFSET = -16560;
+const int32_t OS2_YSUBS_YOFFSET = 0;
+const int32_t OS2_YSUPS_XSIZE = -25944;
+const int32_t OS2_YSUPS_YSIZE = -27176;
+const int32_t OS2_YSUPS_XOFFSET = -16376;
+const int32_t OS2_YSUPS_YOFFSET = 1;
+const int32_t OS2_YSTRIKEOUT_SIZE = 12312;
+const int32_t OS2_YSTRIKEOUT_POS = -16224;
+const int32_t OS2_SFAMILY_CLASS = 0;
+const byte_t OS2_PANOSE[] = { 2, 11, 6, 3, 6, 1, 0, 0, 0, 0 };
+const int64_t OS2_UL_UNICODE_RANGE1 = 0xE00002FFL;
+const int64_t OS2_UL_UNICODE_RANGE2 = 0x520020FBL;
+const int64_t OS2_UL_UNICODE_RANGE3 = 0L;
+const int64_t OS2_UL_UNICODE_RANGE4 = 0L;
+const byte_t OS2_ACH_VEND_ID[] = { 'P', 'f', 'E', 'd' };
+const int32_t OS2_FS_SELECTION = 0x0040;
+const int32_t OS2_US_FIRST_CHAR_IDX = 0x0020;
+const int32_t OS2_US_LAST_CHAR_IDX = 0xFFFF;
+const int32_t OS2_STYPO_ASCENDER = 1597;
+const int32_t OS2_STYPO_DESCENDER = -451;
+const int32_t OS2_STYPO_LINE_GAP = 0;
+const int32_t OS2_US_WIN_ASCENT = 2023;
+const int32_t OS2_US_WIN_DESCENT = 648;
+const int64_t OS2_UL_CODE_PAGE_RANGE1 = 0x2000019FL;
+const int64_t OS2_UL_CODE_PAGE_RANGE2 = 0x00000000L;
+
+static bool VerifyOS_2(Table* table) {
+  OS2TablePtr os2 = down_cast<OS2Table*>(table);
+  if (os2 == NULL) {
+    return false;
+  }
+
+  EXPECT_EQ(os2->TableVersion(), OS2_VERSION);
+  EXPECT_EQ(os2->XAvgCharWidth(), OS2_XAVG_CHAR_WIDTH);
+  EXPECT_EQ(os2->UsWeightClass(), OS2_US_WEIGHT_CLASS);
+  EXPECT_EQ(os2->UsWidthClass(), OS2_US_WIDTH_CLASS);
+  EXPECT_EQ(os2->FsType(), OS2_FS_TYPE);
+  EXPECT_EQ(os2->YSubscriptXSize(), OS2_YSUBS_XSIZE);
+  EXPECT_EQ(os2->YSubscriptYSize(), OS2_YSUBS_YSIZE);
+  EXPECT_EQ(os2->YSubscriptXOffset(), OS2_YSUBS_XOFFSET);
+  EXPECT_EQ(os2->YSubscriptYOffset(), OS2_YSUBS_YOFFSET);
+  EXPECT_EQ(os2->YSuperscriptXSize(), OS2_YSUPS_XSIZE);
+  EXPECT_EQ(os2->YSuperscriptYSize(), OS2_YSUPS_YSIZE);
+  EXPECT_EQ(os2->YSuperscriptXOffset(), OS2_YSUPS_XOFFSET);
+  EXPECT_EQ(os2->YSuperscriptYOffset(), OS2_YSUPS_YOFFSET);
+  EXPECT_EQ(os2->YStrikeoutSize(), OS2_YSTRIKEOUT_SIZE);
+  EXPECT_EQ(os2->YStrikeoutPosition(), OS2_YSTRIKEOUT_POS);
+  EXPECT_EQ(os2->SFamilyClass(), OS2_SFAMILY_CLASS);
+
+  ByteVector panose;
+  os2->Panose(&panose);
+  EXPECT_EQ(panose.size(), sizeof(OS2_PANOSE));
+  for (size_t i = 0; i < panose.size(); ++i) {
+    EXPECT_EQ(panose[i], OS2_PANOSE[i]);
+  }
+
+  EXPECT_EQ(os2->UlUnicodeRange1(), OS2_UL_UNICODE_RANGE1);
+  EXPECT_EQ(os2->UlUnicodeRange2(), OS2_UL_UNICODE_RANGE2);
+  EXPECT_EQ(os2->UlUnicodeRange3(), OS2_UL_UNICODE_RANGE3);
+  EXPECT_EQ(os2->UlUnicodeRange4(), OS2_UL_UNICODE_RANGE4);
+
+  ByteVector vend_id;
+  os2->AchVendId(&vend_id);
+  EXPECT_EQ(vend_id.size(), sizeof(OS2_ACH_VEND_ID));
+  for (size_t i = 0; i < vend_id.size(); ++i) {
+    EXPECT_EQ(vend_id[i], OS2_ACH_VEND_ID[i]);
+  }
+
+  EXPECT_EQ(os2->FsSelection(), OS2_FS_SELECTION);
+  EXPECT_EQ(os2->UsFirstCharIndex(), OS2_US_FIRST_CHAR_IDX);
+  EXPECT_EQ(os2->UsLastCharIndex(), OS2_US_LAST_CHAR_IDX);
+  EXPECT_EQ(os2->STypoAscender(), OS2_STYPO_ASCENDER);
+  EXPECT_EQ(os2->STypoDescender(), OS2_STYPO_DESCENDER);
+  EXPECT_EQ(os2->STypoLineGap(), OS2_STYPO_LINE_GAP);
+  EXPECT_EQ(os2->UsWinAscent(), OS2_US_WIN_ASCENT);
+  EXPECT_EQ(os2->UsWinDescent(), OS2_US_WIN_DESCENT);
+  EXPECT_EQ(os2->UlCodePageRange1(), OS2_UL_CODE_PAGE_RANGE1);
+  EXPECT_EQ(os2->UlCodePageRange2(), OS2_UL_CODE_PAGE_RANGE2);
+
+  // TODO(arthurhsu): SxHeight() not tested
+  // TODO(arthurhsu): SCapHeight() not tested
+  // TODO(arthurhsu): UsDefaultChar() not tested
+  // TODO(arthurhsu): UsBreakChar() not tested
+  // TODO(arthurhsu): UsMaxContext() not tested
+
+  return true;
+}
+
+bool VerifyOS_2(Table* original, Table* target) {
+  EXPECT_TRUE(VerifyOS_2(original));
+  EXPECT_TRUE(VerifyOS_2(target));
+  return true;
+}
+
+}  // namespace sfntly
