diff --git a/cpp/.SConstruct.swp b/cpp/.SConstruct.swp
deleted file mode 100644
index 402a853..0000000
--- a/cpp/.SConstruct.swp
+++ /dev/null
Binary files differ
diff --git a/cpp/Inconsolata-Regular.woff2 b/cpp/Inconsolata-Regular.woff2
deleted file mode 100644
index ddfefb3..0000000
--- a/cpp/Inconsolata-Regular.woff2
+++ /dev/null
Binary files differ
diff --git a/cpp/README b/cpp/README
deleted file mode 100644
index 6c40119..0000000
--- a/cpp/README
+++ /dev/null
@@ -1,44 +0,0 @@
-To build:
-
-Check out a recent version of OTS, so that ots-read-only/ is alongside cpp/
-
-Cd into cpp, and run "scons".
-
-Then, decompress a font using ./woff2-decompress font.wof2 > font.ttf .
-
-An example font is provided (Inconsolata-Regular.wof2). In this snapshot,
-it contains no actual compression, but does apply the glyf table transform
-and has the file format and structure as described in the current draft
-of the "WOFF Ultra Condensed file format" doc.
-
-That said, it is possible to get reliable estimates, and at the very least,
-bounds, on the compression efficiency, with the confidence that the
-compression is reversible. Running the compressor and doing a whole-file
-compression with a standard entropy coder such as gzip or lzma will yield
-a file size within a few dozen bytes or so of using a single entropy coded
-stream in the final file format.
-
-Another limitation of the current implementation snapshot is that it
-doesn't implement continue streams. These will follow shortly.
-
-= Building with lzma =
-
-The lzma-enabled build is made with gyp instead of scons. Right now, the build
-requires patching a clean copy of OTS. (And thanks to Bashi for the patch!)
-
-- Download GYP from http://code.google.com/p/gyp/
-- Download clean OTS sources:
-% svn checkout http://ots.googlecode.com/svn/trunk/ ots-read-only
-- Apply patch
-% cd ots-read-only; patch -p0 < ../ots-lzma.patch
-- Run gyp to generate Makefile
-% cd ../cpp; gyp --depth=. -f make woff2.gyp
-- Build
-% make
-
-Now run:
-
-out/Default/woff2-decompress Inconsolata-Regular-lzma.wof2 > i.ttf
-
-We expect the build recipes to be cleaned up before the code is ready for
-production, but this should be good enough for testing.
diff --git a/cpp/SConstruct b/cpp/SConstruct
deleted file mode 100644
index 4ec2e45..0000000
--- a/cpp/SConstruct
+++ /dev/null
@@ -1,52 +0,0 @@
-# Build script for Linux
-# Note: this script DOESN'T include LZMA. Use the gyp-based build instead.
-#
-# Usage:
-#   $ cd ots/test/
-#   $ scons -c         # clean
-#   $ scons            # build
-#
-
-# Since the validator-checker tool might handle malicious font files, all hardening options for recent g++/ld are enabled just in case.
-# See http://wiki.debian.org/Hardening for details.
-env = Environment(CCFLAGS = ['-O2', '-I../ots-read-only/include', '-I../ots-read-only/src', '-I/usr/include/freetype2', '-ggdb', '-Wall', '-W', '-Wno-unused-parameter', '-fno-strict-aliasing', '-fPIE', '-fstack-protector', '-D_FORTIFY_SOURCE=2', '-DOTS_DEBUG'], LINKFLAGS = ['-ggdb', '-Wl,-z,relro', '-Wl,-z,now', '-pie', '-lz'])
- 
-env.Library('libwoff2.a',
-            [
-            'woff2.cc',
-
-            # Just build all of OTS to keep things simple for now. We could
-            # refactor so that we only compile the few support routines from
-            # ots.cc that we need.
-            '../ots-read-only/src/cff.cc',
-	          '../ots-read-only/src/cff_type2_charstring.cc',
-	          '../ots-read-only/src/cmap.cc',
-	          '../ots-read-only/src/cvt.cc',
-	          '../ots-read-only/src/fpgm.cc',
-	          '../ots-read-only/src/gasp.cc',
-	          '../ots-read-only/src/gdef.cc',
-	          '../ots-read-only/src/glyf.cc',
-	          '../ots-read-only/src/gpos.cc',
-	          '../ots-read-only/src/gsub.cc',
-	          '../ots-read-only/src/hdmx.cc',
-	          '../ots-read-only/src/head.cc',
-	          '../ots-read-only/src/hhea.cc',
-	          '../ots-read-only/src/hmtx.cc',
-	          '../ots-read-only/src/kern.cc',
-	          '../ots-read-only/src/layout.cc',
-	          '../ots-read-only/src/loca.cc',
-	          '../ots-read-only/src/ltsh.cc',
-	          '../ots-read-only/src/maxp.cc',
-	          '../ots-read-only/src/metrics.cc',
-	          '../ots-read-only/src/name.cc',
-	          '../ots-read-only/src/os2.cc',
-	          '../ots-read-only/src/ots.cc',
-	          '../ots-read-only/src/post.cc',
-	          '../ots-read-only/src/prep.cc',
-	          '../ots-read-only/src/vdmx.cc',
-	          '../ots-read-only/src/vhea.cc',
-	          '../ots-read-only/src/vmtx.cc',
-	          '../ots-read-only/src/vorg.cc'
-            ])
-
-env.Program('woff2-decompress.cc', LIBS = ['woff2'], LIBPATH='.')
diff --git a/cpp/woff2-decompress.cc b/cpp/woff2-decompress.cc
deleted file mode 100644
index dc9a281..0000000
--- a/cpp/woff2-decompress.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// A very simple commandline tool for decompressing woff2 format files
-// (given as argc[1]), writing the decompressed version to stdout.
-
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include <cstdio>
-#include <cstdlib>
-
-#include "opentype-sanitiser.h"
-#include "woff2.h"
-
-namespace {
-
-int Usage(const char *argv0) {
-  std::fprintf(stderr, "Usage: %s woff2_file > dest_ttf_file\n", argv0);
-  return 1;
-}
-
-}  // namespace
-
-int main(int argc, char **argv) {
-  if (argc != 2) return Usage(argv[0]);
-  if (::isatty(1)) return Usage(argv[0]);
-
-  const int fd = ::open(argv[1], O_RDONLY);
-  if (fd < 0) {
-    ::perror("open");
-    return 1;
-  }
-
-  struct stat st;
-  ::fstat(fd, &st);
-
-  uint8_t *data = new uint8_t[st.st_size];
-  if (::read(fd, data, st.st_size) != st.st_size) {
-    ::perror("read");
-    return 1;
-  }
-  ::close(fd);
-
-  size_t decompressed_size = ots::ComputeWOFF2FinalSize(data, st.st_size);
-  if (decompressed_size == 0) {
-    std::fprintf(stderr, "Error computing decompressed file size!\n");
-    return 1;
-  }
-  uint8_t *buf = new uint8_t[decompressed_size];
-  const bool result = ots::ConvertWOFF2ToTTF(buf, decompressed_size,
-    data, st.st_size);
-
-  if (!result) {
-    std::fprintf(stderr, "Failed to decompress file!\n");
-  }
-  fwrite(buf, 1, decompressed_size, stdout);
-  return !result;
-}
diff --git a/cpp/woff2.cc b/cpp/woff2.cc
deleted file mode 100644
index 6fe543c..0000000
--- a/cpp/woff2.cc
+++ /dev/null
@@ -1,1035 +0,0 @@
-// Copyright (c) 2012 Google Inc. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This is the implementation of decompression of the proposed WOFF Ultra
-// Condensed file format.
-
-// For now, use of LZMA is conditional, because the build is trickier. When
-// that gets all sorted out, we can get rid of these ifdefs.
-#define USE_LZMA
-
-#include <vector>
-
-#ifdef USE_LZMA
-#include "third_party/lzma_sdk/LzmaLib.h"
-#endif
-
-#include <zlib.h>
-
-#include "opentype-sanitiser.h"
-#include "ots-memory-stream.h"
-
-#include "ots.h"
-#include "woff2.h"
-
-namespace {
-
-// simple glyph flags
-const int kGlyfOnCurve = 1 << 0;
-const int kGlyfXShort = 1 << 1;
-const int kGlyfYShort = 1 << 2;
-const int kGlyfRepeat = 1 << 3;
-const int kGlyfThisXIsSame = 1 << 4;
-const int kGlyfThisYIsSame = 1 << 5;
-
-// composite glyph flags
-const int FLAG_ARG_1_AND_2_ARE_WORDS = 1 << 0;
-const int FLAG_ARGS_ARE_XY_VALUES = 1 << 1;
-const int FLAG_ROUND_XY_TO_GRID = 1 << 2;
-const int FLAG_WE_HAVE_A_SCALE = 1 << 3;
-const int FLAG_RESERVED = 1 << 4;
-const int FLAG_MORE_COMPONENTS = 1 << 5;
-const int FLAG_WE_HAVE_AN_X_AND_Y_SCALE = 1 << 6;
-const int FLAG_WE_HAVE_A_TWO_BY_TWO = 1 << 7;
-const int FLAG_WE_HAVE_INSTRUCTIONS = 1 << 8;
-const int FLAG_USE_MY_METRICS = 1 << 9;
-const int FLAG_OVERLAP_COMPOUND = 1 << 10;
-const int FLAG_SCALED_COMPONENT_OFFSET = 1 << 11;
-const int FLAG_UNSCALED_COMPONENT_OFFSET = 1 << 12;
-
-const size_t kSfntHeaderSize = 12;
-const size_t kSfntEntrySize = 16;
-const size_t kCheckSumAdjustmentOffset = 8;
-
-const size_t kEndPtsOfContoursOffset = 10;
-const size_t kCompositeGlyphBegin = 10;
-
-// Note that the byte order is big-endian, not the same as ots.cc
-#define TAG(a, b, c, d) ((a << 24) | (b << 16) | (c << 8) | d)
-
-const unsigned int kWoff2FlagsContinueStream = 1 << 4;
-const unsigned int kWoff2FlagsTransform = 1 << 5;
-
-const size_t kWoff2HeaderSize = 44;
-const size_t kWoff2EntrySize = 20;
-
-const size_t kLzmaHeaderSize = 13;
-
-// Compression type values common to both short and long formats
-const uint32_t kCompressionTypeMask = 0xf;
-const uint32_t kCompressionTypeNone = 0;
-const uint32_t kCompressionTypeGzip = 1;
-const uint32_t kCompressionTypeLzma = 2;
-
-// This is a special value for the short format only, as described in
-// "Design for compressed header format" in draft doc.
-const uint32_t kShortFlagsContinue = 3;
-
-struct Point {
-  int x;
-  int y;
-  bool on_curve;
-};
-
-struct Table {
-  uint32_t tag;
-  uint32_t flags;
-  uint32_t src_offset;
-  uint32_t src_length;
-
-  uint32_t transform_length;
-
-  uint32_t dst_offset;
-  uint32_t dst_length;
-};
-
-// TODO: copied from ots.cc, probably shouldn't be duplicated.
-// Round a value up to the nearest multiple of 4. Don't round the value in the
-// case that rounding up overflows.
-template<typename T> T Round4(T value) {
-  if (std::numeric_limits<T>::max() - value < 3) {
-    return value;
-  }
-  return (value + 3) & ~3;
-}
-
-// Based on section 6.1.1 of MicroType Express draft spec
-bool Read255UShort(ots::Buffer* buf, unsigned int* value) {
-  static const int kWordCode = 253;
-  static const int kOneMoreByteCode2 = 254;
-  static const int kOneMoreByteCode1 = 255;
-  static const int kLowestUCode = 253;
-  uint8_t code = 0;
-  if (!buf->ReadU8(&code)) {
-    return OTS_FAILURE();
-  }
-  if (code == kWordCode) {
-    uint16_t result = 0;
-    if (!buf->ReadU16(&result)) {
-      return OTS_FAILURE();
-    }
-    *value = result;
-    return true;
-  } else if (code == kOneMoreByteCode1) {
-    uint8_t result = 0;
-    if (!buf->ReadU8(&result)) {
-      return OTS_FAILURE();
-    }
-    *value = result + kLowestUCode;
-    return true;
-  } else if (code == kOneMoreByteCode2) {
-    uint8_t result = 0;
-    if (!buf->ReadU8(&result)) {
-      return OTS_FAILURE();
-    }
-    *value = result + kLowestUCode * 2;
-    return true;
-  } else {
-    *value = code;
-    return true;
-  }
-}
-
-bool ReadBase128(ots::Buffer* buf, uint32_t* value) {
-  uint32_t result = 0;
-  for (size_t i = 0; i < 5; ++i) {
-    uint8_t code = 0;
-    if (!buf->ReadU8(&code)) {
-      return OTS_FAILURE();
-    }
-    // If any of the top seven bits are set then we're about to overflow.
-    if (result & 0xe0000000) {
-      return OTS_FAILURE();
-    }
-    result = (result << 7) | (code & 0x7f);
-    if ((code & 0x80) == 0) {
-      *value = result;
-      return true;
-    }
-  }
-  // Make sure not to exceed the size bound
-  return OTS_FAILURE();
-}
-
-size_t StoreU32(uint8_t* dst, size_t offset, uint32_t x) {
-  dst[offset] = x >> 24;
-  dst[offset + 1] = x >> 16;
-  dst[offset + 2] = x >> 8;
-  dst[offset + 3] = x;
-  return offset + 4;
-}
-
-size_t Store16(uint8_t* dst, size_t offset, int x) {
-  dst[offset] = x >> 8;
-  dst[offset + 1] = x;
-  return offset + 2;
-}
-
-int WithSign(int flag, int baseval) {
-  // Precondition: 0 <= baseval < 65536 (to avoid integer overflow)
-  return (flag & 1) ? baseval : -baseval;
-}
-
-bool TripletDecode(const uint8_t* flags_in, const uint8_t* in, size_t in_size,
-    unsigned int n_points, std::vector<Point>* result,
-    size_t* in_bytes_consumed) {
-  int x = 0;
-  int y = 0;
-
-  if (n_points > in_size) {
-    return OTS_FAILURE();
-  }
-  unsigned int triplet_index = 0;
-
-  for (unsigned int i = 0; i < n_points; ++i) {
-    uint8_t flag = flags_in[i];
-    bool on_curve = !(flag >> 7);
-    flag &= 0x7f;
-    unsigned int n_data_bytes;
-    if (flag < 84) {
-      n_data_bytes = 1;
-    } else if (flag < 120) {
-      n_data_bytes = 2;
-    } else if (flag < 124) {
-      n_data_bytes = 3;
-    } else {
-      n_data_bytes = 4;
-    }
-    if (triplet_index + n_data_bytes > in_size ||
-        triplet_index + n_data_bytes < triplet_index) {
-      return OTS_FAILURE();
-    }
-    int dx, dy;
-    if (flag < 10) {
-      dx = 0;
-      dy = WithSign(flag, ((flag & 14) << 7) + in[triplet_index]);
-    } else if (flag < 20) {
-      dx = WithSign(flag, (((flag - 10) & 14) << 7) + in[triplet_index]);
-      dy = 0;
-    } else if (flag < 84) {
-      int b0 = flag - 20;
-      int b1 = in[triplet_index];
-      dx = WithSign(flag, 1 + (b0 & 0x30) + (b1 >> 4));
-      dy = WithSign(flag >> 1, 1 + ((b0 & 0x0c) << 2) + (b1 & 0x0f));
-    } else if (flag < 120) {
-      int b0 = flag - 84;
-      dx = WithSign(flag, 1 + ((b0 / 12) << 8) + in[triplet_index]);
-      dy = WithSign(flag >> 1,
-                    1 + (((b0 % 12) >> 2) << 8) + in[triplet_index + 1]);
-    } else if (flag < 124) {
-      int b2 = in[triplet_index + 1];
-      dx = WithSign(flag, (in[triplet_index] << 4) + (b2 >> 4));
-      dy = WithSign(flag >> 1, ((b2 & 0x0f) << 8) + in[triplet_index + 2]);
-    } else {
-      dx = WithSign(flag, (in[triplet_index] << 8) + in[triplet_index + 1]);
-      dy = WithSign(flag >> 1,
-          (in[triplet_index + 2] << 8) + in[triplet_index + 3]);
-    }
-    triplet_index += n_data_bytes;
-    // Possible overflow but coordinate values are not security sensitive
-    x += dx;
-    y += dy;
-    result->push_back(Point());
-    Point& back = result->back();
-    back.x = x;
-    back.y = y;
-    back.on_curve = on_curve;
-  }
-  *in_bytes_consumed = triplet_index;
-  return true;
-}
-
-// This function stores just the point data. On entry, dst points to the
-// beginning of a simple glyph. Returns true on success.
-bool StorePoints(const std::vector<Point>& points,
-    unsigned int n_contours, unsigned int instruction_length,
-    uint8_t* dst, size_t dst_size, size_t* glyph_size) {
-  // I believe that n_contours < 65536, in which case this is safe. However, a
-  // comment and/or an assert would be good.
-  unsigned int flag_offset = kEndPtsOfContoursOffset + 2 * n_contours + 2 +
-    instruction_length;
-  int last_flag = -1;
-  int repeat_count = 0;
-  int last_x = 0;
-  int last_y = 0;
-  unsigned int x_bytes = 0;
-  unsigned int y_bytes = 0;
-
-  for (unsigned int i = 0; i < points.size(); ++i) {
-    const Point& point = points[i];
-    int flag = point.on_curve ? kGlyfOnCurve : 0;
-    int dx = point.x - last_x;
-    int dy = point.y - last_y;
-    if (dx == 0) {
-      flag |= kGlyfThisXIsSame;
-    } else if (dx > -256 && dx < 256) {
-      flag |= kGlyfXShort | (dx > 0 ? kGlyfThisXIsSame : 0);
-      x_bytes += 1;
-    } else {
-      x_bytes += 2;
-    }
-    if (dy == 0) {
-      flag |= kGlyfThisYIsSame;
-    } else if (dy > -256 && dy < 256) {
-      flag |= kGlyfYShort | (dy > 0 ? kGlyfThisYIsSame : 0);
-      y_bytes += 1;
-    } else {
-      y_bytes += 2;
-    }
-
-    if (flag == last_flag && repeat_count != 255) {
-      dst[flag_offset - 1] |= kGlyfRepeat;
-      repeat_count++;
-    } else {
-      if (repeat_count != 0) {
-        if (flag_offset >= dst_size) {
-          return OTS_FAILURE();
-        }
-        dst[flag_offset++] = repeat_count;
-      }
-      if (flag_offset >= dst_size) {
-        return OTS_FAILURE();
-      }
-      dst[flag_offset++] = flag;
-      repeat_count = 0;
-    }
-    last_x = point.x;
-    last_y = point.y;
-    last_flag = flag;
-  }
-
-  if (repeat_count != 0) {
-    if (flag_offset >= dst_size) {
-      return OTS_FAILURE();
-    }
-    dst[flag_offset++] = repeat_count;
-  }
-  unsigned int xy_bytes = x_bytes + y_bytes;
-  if (xy_bytes < x_bytes ||
-      flag_offset + xy_bytes < flag_offset ||
-      flag_offset + xy_bytes > dst_size) {
-    return OTS_FAILURE();
-  }
-
-  int x_offset = flag_offset;
-  int y_offset = flag_offset + x_bytes;
-  last_x = 0;
-  last_y = 0;
-  for (unsigned int i = 0; i < points.size(); ++i) {
-    int dx = points[i].x - last_x;
-    if (dx == 0) {
-      // pass
-    } else if (dx > -256 && dx < 256) {
-      dst[x_offset++] = std::abs(dx);
-    } else {
-      // will always fit for valid input, but overflow is harmless
-      x_offset = Store16(dst, x_offset, dx);
-    }
-    last_x += dx;
-    int dy = points[i].y - last_y;
-    if (dy == 0) {
-      // pass
-    } else if (dy > -256 && dy < 256) {
-      dst[y_offset++] = std::abs(dy);
-    } else {
-      y_offset = Store16(dst, y_offset, dy);
-    }
-    last_y += dy;
-  }
-  *glyph_size = y_offset;
-  return true;
-}
-
-// Compute the bounding box of the coordinates, and store into a glyf buffer.
-// A precondition is that there are at least 10 bytes available.
-void ComputeBbox(const std::vector<Point>& points, uint8_t* dst) {
-  int x_min = 0;
-  int y_min = 0;
-  int x_max = 0;
-  int y_max = 0;
-  
-  for (unsigned int i = 0; i < points.size(); ++i) {
-    int x = points[i].x;
-    int y = points[i].y;
-    if (i == 0 || x < x_min) x_min = x;
-    if (i == 0 || x > x_max) x_max = x;
-    if (i == 0 || y < y_min) y_min = y;
-    if (i == 0 || y > y_max) y_max = y;
-  }
-  size_t offset = 2;
-  offset = Store16(dst, offset, x_min);
-  offset = Store16(dst, offset, y_min);
-  offset = Store16(dst, offset, x_max);
-  offset = Store16(dst, offset, y_max);
-}
-
-// Process entire bbox stream. This is done as a separate pass to allow for
-// composite bbox computations (an optional more aggressive transform).
-bool ProcessBboxStream(ots::Buffer* bbox_stream, unsigned int n_glyphs,
-    const std::vector<uint32_t>& loca_values, uint8_t* glyf_buf,
-    size_t glyf_buf_length) {
-  const uint8_t* buf = bbox_stream->buffer();
-  if (n_glyphs >= 65536 || loca_values.size() != n_glyphs + 1) {
-    return OTS_FAILURE();
-  }
-  // Safe because n_glyphs is bounded
-  unsigned int bitmap_length = ((n_glyphs + 31) >> 5) << 2;
-  if (!bbox_stream->Skip(bitmap_length)) {
-    return OTS_FAILURE();
-  }
-  for (unsigned int i = 0; i < n_glyphs; ++i) {
-    if (buf[i >> 3] & (0x80 >> (i & 7))) {
-      uint32_t loca_offset = loca_values[i];
-      if (loca_values[i + 1] - loca_offset < kEndPtsOfContoursOffset) {
-        return OTS_FAILURE();
-      }
-      if (glyf_buf_length < 2 + 10 ||
-          loca_offset > glyf_buf_length - 2 - 10) {
-        return OTS_FAILURE();
-      }
-      if (!bbox_stream->Read(glyf_buf + loca_offset + 2, 8)) {
-        return OTS_FAILURE();
-      }
-    }
-  }
-  return true;
-}
-
-bool ProcessComposite(ots::Buffer* composite_stream, uint8_t* dst,
-    size_t dst_size, size_t* glyph_size, bool* have_instructions) {
-  size_t start_offset = composite_stream->offset();
-  bool we_have_instructions = false;
-
-  uint16_t flags = FLAG_MORE_COMPONENTS;
-  while (flags & FLAG_MORE_COMPONENTS) {
-    if (!composite_stream->ReadU16(&flags)) {
-      return OTS_FAILURE();
-    }
-    we_have_instructions |= (flags & FLAG_WE_HAVE_INSTRUCTIONS) != 0;
-    size_t arg_size = 2;  // glyph index
-    if (flags & FLAG_ARG_1_AND_2_ARE_WORDS) {
-      arg_size += 4;
-    } else {
-      arg_size += 2;
-    }
-    if (flags & FLAG_WE_HAVE_A_SCALE) {
-      arg_size += 2;
-    } else if (flags & FLAG_WE_HAVE_AN_X_AND_Y_SCALE) {
-      arg_size += 4;
-    } else if (flags & FLAG_WE_HAVE_A_TWO_BY_TWO) {
-      arg_size += 8;
-    }
-    if (!composite_stream->Skip(arg_size)) {
-      return OTS_FAILURE();
-    }
-  }
-  size_t composite_glyph_size = composite_stream->offset() - start_offset;
-  if (composite_glyph_size + kCompositeGlyphBegin > dst_size) {
-    return OTS_FAILURE();
-  }
-  Store16(dst, 0, 0xffff);  // nContours = -1 for composite glyph
-  std::memcpy(dst + kCompositeGlyphBegin,
-      composite_stream->buffer() + start_offset,
-      composite_glyph_size);
-  *glyph_size = kCompositeGlyphBegin + composite_glyph_size;
-  *have_instructions = we_have_instructions;
-  return true;
-}
-
-// Build TrueType loca table
-bool StoreLoca(const std::vector<uint32_t>& loca_values, int index_format,
-    uint8_t* dst, size_t dst_size) {
-  const uint64_t loca_size = loca_values.size();
-  const uint64_t offset_size = index_format ? 4 : 2;
-  if ((loca_size << 2) >> 2 != loca_size) {
-    return OTS_FAILURE();
-  }
-  if (offset_size * loca_size > dst_size) {
-    return OTS_FAILURE();
-  }
-  size_t offset = 0;
-  for (size_t i = 0; i < loca_values.size(); ++i) {
-    uint32_t value = loca_values[i];
-    if (index_format) {
-      offset = StoreU32(dst, offset, value);
-    } else {
-      offset = Store16(dst, offset, value >> 1);
-    }
-  }
-  return true;
-}
-
-// Reconstruct entire glyf table based on transformed original
-bool ReconstructGlyf(const uint8_t* data, size_t data_size,
-    uint8_t* dst, size_t dst_size,
-    uint8_t* loca_buf, size_t loca_size) {
-  static const int kNumSubStreams = 7;
-  ots::Buffer file(data, data_size);
-  uint32_t version;
-  std::vector<std::pair<const uint8_t*, size_t> > substreams(kNumSubStreams);
-
-  if (!file.ReadU32(&version)) {
-    return OTS_FAILURE();
-  }
-  uint16_t num_glyphs;
-  uint16_t index_format;
-  if (!file.ReadU16(&num_glyphs) ||
-      !file.ReadU16(&index_format)) {
-    return OTS_FAILURE();
-  }
-  unsigned int offset = (2 + kNumSubStreams) * 4;
-  if (offset > data_size) {
-    return OTS_FAILURE();
-  }
-  // Invariant from here on: data_size >= offset
-  for (int i = 0; i < kNumSubStreams; ++i) {
-    uint32_t substream_size;
-    if (!file.ReadU32(&substream_size)) {
-      return OTS_FAILURE();
-    }
-    if (substream_size > data_size - offset) {
-      return OTS_FAILURE();
-    }
-    substreams[i] = std::make_pair(data + offset, substream_size);
-    offset += substream_size;
-  }
-  ots::Buffer n_contour_stream(substreams[0].first, substreams[0].second);
-  ots::Buffer n_points_stream(substreams[1].first, substreams[1].second);
-  ots::Buffer flag_stream(substreams[2].first, substreams[2].second);
-  ots::Buffer glyph_stream(substreams[3].first, substreams[3].second);
-  ots::Buffer composite_stream(substreams[4].first, substreams[4].second);
-  ots::Buffer bbox_stream(substreams[5].first, substreams[5].second);
-  ots::Buffer instruction_stream(substreams[6].first, substreams[6].second);
-  
-  std::vector<uint32_t> loca_values(num_glyphs + 1);
-  std::vector<unsigned int> n_points_vec;
-  std::vector<Point> points;
-  uint32_t loca_offset = 0;
-  for (unsigned int i = 0; i < num_glyphs; ++i) {
-    size_t glyph_size = 0;
-    uint16_t n_contours = 0;
-    if (!n_contour_stream.ReadU16(&n_contours)) {
-      return OTS_FAILURE();
-    }
-    uint8_t* glyf_dst = dst + loca_offset;
-    size_t glyf_dst_size = dst_size - loca_offset;
-    if (n_contours == 0xffff) {
-      // composite glyph
-      bool have_instructions = false;
-      unsigned int instruction_size = 0;
-      if (!ProcessComposite(&composite_stream, glyf_dst, glyf_dst_size,
-            &glyph_size, &have_instructions)) {
-        return OTS_FAILURE();
-      }
-      if (have_instructions) {
-        if (!Read255UShort(&glyph_stream, &instruction_size)) {
-          return OTS_FAILURE();
-        }
-        if (instruction_size + 2 > glyf_dst_size - glyph_size) {
-          return OTS_FAILURE();
-        }
-        Store16(glyf_dst, glyph_size, instruction_size);
-        if (!instruction_stream.Read(glyf_dst + glyph_size + 2,
-              instruction_size)) {
-          return OTS_FAILURE();
-        }
-        glyph_size += instruction_size + 2;
-      }
-    } else if (n_contours > 0) {
-      // simple glyph
-      n_points_vec.clear();
-      points.clear();
-      unsigned int total_n_points = 0;
-      unsigned int n_points_contour;
-      for (unsigned int j = 0; j < n_contours; ++j) {
-        if (!Read255UShort(&n_points_stream, &n_points_contour)) {
-          return OTS_FAILURE();
-        }
-        n_points_vec.push_back(n_points_contour);
-        if (total_n_points + n_points_contour < total_n_points) {
-          return OTS_FAILURE();
-        }
-        total_n_points += n_points_contour;
-      }
-      unsigned int flag_size = total_n_points;
-      if (flag_size > flag_stream.length() - flag_stream.offset()) {
-        return OTS_FAILURE();
-      }
-      const uint8_t* flags_buf = flag_stream.buffer() + flag_stream.offset();
-      const uint8_t* triplet_buf = glyph_stream.buffer() +
-        glyph_stream.offset();
-      size_t triplet_size = glyph_stream.length() - glyph_stream.offset();
-      size_t triplet_bytes_consumed = 0;
-      if (!TripletDecode(flags_buf, triplet_buf, triplet_size, total_n_points,
-            &points, &triplet_bytes_consumed)) {
-        return OTS_FAILURE();
-      }
-      const uint32_t header_and_endpts_contours_size =
-          kEndPtsOfContoursOffset + 2 * n_contours;
-      if (glyf_dst_size < header_and_endpts_contours_size) {
-        return OTS_FAILURE();
-      }
-      Store16(glyf_dst, 0, n_contours);
-      ComputeBbox(points, glyf_dst);
-      size_t offset = kEndPtsOfContoursOffset;
-      int end_point = -1;
-      for (unsigned int contour_ix = 0; contour_ix < n_contours; ++contour_ix) {
-        end_point += n_points_vec[contour_ix];
-        if (end_point >= 65536) {
-          return OTS_FAILURE();
-        }
-        offset = Store16(glyf_dst, offset, end_point);
-      }
-      if (!flag_stream.Skip(flag_size)) {
-        return OTS_FAILURE();
-      }
-      if (!glyph_stream.Skip(triplet_bytes_consumed)) {
-        return OTS_FAILURE();
-      }
-      unsigned int instruction_size;
-      if (!Read255UShort(&glyph_stream, &instruction_size)) {
-        return OTS_FAILURE();
-      }
-      if (glyf_dst_size - header_and_endpts_contours_size <
-          instruction_size + 2) {
-        return OTS_FAILURE();
-      }
-      uint8_t* instruction_dst = glyf_dst + header_and_endpts_contours_size;
-      Store16(instruction_dst, 0, instruction_size);
-      if (!instruction_stream.Read(instruction_dst + 2, instruction_size)) {
-        return OTS_FAILURE();
-      }
-      if (!StorePoints(points, n_contours, instruction_size,
-            glyf_dst, glyf_dst_size, &glyph_size)) {
-        return OTS_FAILURE();
-      }
-    } else {
-      glyph_size = 0;
-    }
-    loca_values[i] = loca_offset;
-    if (glyph_size + 3 < glyph_size) {
-      return OTS_FAILURE();
-    }
-    glyph_size = Round4(glyph_size);
-    if (glyph_size > dst_size - loca_offset) {
-      // This shouldn't happen, but this test defensively maintains the
-      // invariant that loca_offset <= dst_size.
-      return OTS_FAILURE();
-    }
-    loca_offset += glyph_size;
-  }
-  loca_values[num_glyphs] = loca_offset;
-  if (!ProcessBboxStream(&bbox_stream, num_glyphs, loca_values,
-          dst, dst_size)) {
-    return OTS_FAILURE();
-  }
-  return StoreLoca(loca_values, index_format, loca_buf, loca_size);
-}
-
-// This is linear search, but could be changed to binary because we
-// do have a guarantee that the tables are sorted by tag. But the total
-// cpu time is expected to be very small in any case.
-const Table* FindTable(const std::vector<Table>& tables, uint32_t tag) {
-  size_t n_tables = tables.size();
-  for (size_t i = 0; i < n_tables; ++i) {
-    if (tables[i].tag == tag) {
-      return &tables[i];
-    }
-  }
-  return NULL;
-}
-
-bool ReconstructTransformed(const std::vector<Table>& tables, uint32_t tag,
-    const uint8_t* transformed_buf, size_t transformed_size,
-    uint8_t* dst, size_t dst_length) {
-  if (tag == TAG('g', 'l', 'y', 'f')) {
-    const Table* glyf_table = FindTable(tables, tag);
-    const Table* loca_table = FindTable(tables, TAG('l', 'o', 'c', 'a'));
-    if (glyf_table == NULL || loca_table == NULL) {
-      return OTS_FAILURE();
-    }
-    if (static_cast<uint64_t>(glyf_table->dst_offset + glyf_table->dst_length) >
-        dst_length) {
-      return OTS_FAILURE();
-    }
-    if (static_cast<uint64_t>(loca_table->dst_offset + loca_table->dst_length) >
-        dst_length) {
-      return OTS_FAILURE();
-    }
-    return ReconstructGlyf(transformed_buf, transformed_size,
-        dst + glyf_table->dst_offset, glyf_table->dst_length,
-        dst + loca_table->dst_offset, loca_table->dst_length);
-  } else if (tag == TAG('l', 'o', 'c', 'a')) {
-    // processing was already done by glyf table, but validate
-    if (!FindTable(tables, TAG('g', 'l', 'y', 'f'))) {
-      return OTS_FAILURE();
-    }
-  } else {
-    // transform for the tag is not known
-    return OTS_FAILURE();
-  }
-  return true;
-}
-
-uint32_t ComputeChecksum(const uint8_t* buf, size_t size) {
-  uint32_t checksum = 0;
-  for (size_t i = 0; i < size; i += 4) {
-    // We assume the addition is mod 2^32, which is valid because unsigned
-    checksum += (buf[i] << 24) | (buf[i + 1] << 16) |
-      (buf[i + 2] << 8) | buf[i + 3];
-  }
-  return checksum;
-}
-
-bool FixChecksums(const std::vector<Table>& tables, uint8_t* dst) {
-  const Table* head_table = FindTable(tables, TAG('h', 'e', 'a', 'd'));
-  if (head_table == NULL ||
-      head_table->dst_length < kCheckSumAdjustmentOffset + 4) {
-    return OTS_FAILURE();
-  }
-  size_t adjustment_offset = head_table->dst_offset + kCheckSumAdjustmentOffset;
-  StoreU32(dst, adjustment_offset, 0);
-  size_t n_tables = tables.size();
-  uint32_t file_checksum = 0;
-  for (size_t i = 0; i < n_tables; ++i) {
-    const Table* table = &tables[i];
-    size_t table_length = table->dst_length;
-    uint8_t* table_data = dst + table->dst_offset;
-    uint32_t checksum = ComputeChecksum(table_data, table_length);
-    StoreU32(dst, kSfntHeaderSize + i * kSfntEntrySize + 4, checksum);
-    file_checksum += checksum;
-  }
-  file_checksum += ComputeChecksum(dst,
-      kSfntHeaderSize + kSfntEntrySize * n_tables);
-  uint32_t checksum_adjustment = 0xb1b0afba - file_checksum;
-  StoreU32(dst, adjustment_offset, checksum_adjustment);
-  return true;
-}
-
-bool Woff2Uncompress(uint8_t* dst_buf, size_t dst_size,
-    const uint8_t* src_buf, size_t src_size, uint32_t compression_type) {
-  if (compression_type == kCompressionTypeGzip) {
-    uLongf uncompressed_length = dst_size;
-    int r = uncompress(reinterpret_cast<Bytef *>(dst_buf), &uncompressed_length,
-        src_buf, src_size);
-    if (r != Z_OK || uncompressed_length != dst_size) {
-      return OTS_FAILURE();
-    }
-    return true;
-#ifdef USE_LZMA
-  } else if (compression_type == kCompressionTypeLzma) {
-    if (src_size < kLzmaHeaderSize) {
-      // Make sure we have at least a full Lzma header
-      return OTS_FAILURE();
-    }
-    // TODO: check that size matches (or elide size?)
-    size_t uncompressed_size = dst_size;
-    size_t compressed_size = src_size;
-    int result = LzmaUncompress(dst_buf, &dst_size,
-        src_buf + kLzmaHeaderSize, &compressed_size,
-        src_buf, LZMA_PROPS_SIZE);
-    if (result != SZ_OK || uncompressed_size != dst_size) {
-      return OTS_FAILURE();
-    }
-    return true;
-#endif
-  }
-  // Unknown compression type
-  return OTS_FAILURE();
-}
-
-bool ReadLongDirectory(ots::Buffer* file, std::vector<Table>* tables,
-    size_t num_tables) {
-  for (size_t i = 0; i < num_tables; ++i) {
-    Table* table = &(*tables)[i];
-    if (!file->ReadU32(&table->tag) ||
-        !file->ReadU32(&table->flags) ||
-        !file->ReadU32(&table->src_length) ||
-        !file->ReadU32(&table->transform_length) ||
-        !file->ReadU32(&table->dst_length)) {
-      return OTS_FAILURE();
-    }
-  }
-  return true;
-}
-
-const uint32_t known_tags[29] = {
-  TAG('c', 'm', 'a', 'p'),  // 0
-  TAG('h', 'e', 'a', 'd'),  // 1
-  TAG('h', 'h', 'e', 'a'),  // 2
-  TAG('h', 'm', 't', 'x'),  // 3
-  TAG('m', 'a', 'x', 'p'),  // 4
-  TAG('n', 'a', 'm', 'e'),  // 5
-  TAG('O', 'S', '/', '2'),  // 6
-  TAG('p', 'o', 's', 't'),  // 7
-  TAG('c', 'v', 't', ' '),  // 8
-  TAG('f', 'p', 'g', 'm'),  // 9
-  TAG('g', 'l', 'y', 'f'),  // 10
-  TAG('l', 'o', 'c', 'a'),  // 11
-  TAG('p', 'r', 'e', 'p'),  // 12
-  TAG('C', 'F', 'F', ' '),  // 13
-  TAG('V', 'O', 'R', 'G'),  // 14
-  TAG('E', 'B', 'D', 'T'),  // 15
-  TAG('E', 'B', 'L', 'C'),  // 16
-  TAG('g', 'a', 's', 'p'),  // 17
-  TAG('h', 'd', 'm', 'x'),  // 18
-  TAG('k', 'e', 'r', 'n'),  // 19
-  TAG('L', 'T', 'S', 'H'),  // 20
-  TAG('P', 'C', 'L', 'T'),  // 21
-  TAG('V', 'D', 'M', 'X'),  // 22
-  TAG('v', 'h', 'e', 'a'),  // 23
-  TAG('v', 'm', 't', 'x'),  // 24
-  TAG('B', 'A', 'S', 'E'),  // 25
-  TAG('G', 'D', 'E', 'F'),  // 26
-  TAG('G', 'P', 'O', 'S'),  // 27
-  TAG('G', 'S', 'U', 'B'),  // 28
-};
-
-bool ReadShortDirectory(ots::Buffer* file, std::vector<Table>* tables,
-    size_t num_tables) {
-  uint32_t last_compression_type = 0;
-  for (size_t i = 0; i < num_tables; ++i) {
-    Table* table = &(*tables)[i];
-    uint8_t flag_byte;
-    if (!file->ReadU8(&flag_byte)) {
-      return OTS_FAILURE();
-    }
-    uint32_t tag;
-    if ((flag_byte & 0x1f) == 0x1f) {
-      if (!file->ReadU32(&tag)) {
-        return OTS_FAILURE();
-      }
-    } else {
-      if ((flag_byte & 0x1f) >= (sizeof(known_tags) / sizeof(known_tags[0]))) {
-        return OTS_FAILURE();
-      }
-      tag = known_tags[flag_byte & 0x1f];
-    }
-    uint32_t flags = flag_byte >> 6;
-    if (flags == kShortFlagsContinue) {
-      flags = last_compression_type | kWoff2FlagsContinueStream;
-    } else {
-      if (flags == kCompressionTypeNone ||
-          flags == kCompressionTypeGzip ||
-          flags == kCompressionTypeLzma) {
-        last_compression_type = flags;
-      } else {
-        return OTS_FAILURE();
-      }
-    }
-    if ((flag_byte & 0x20) != 0) {
-      flags |= kWoff2FlagsTransform;
-    }
-    uint32_t dst_length;
-    if (!ReadBase128(file, &dst_length)) {
-      return OTS_FAILURE();
-    }
-    uint32_t transform_length = dst_length;
-    if ((flags & kWoff2FlagsTransform) != 0) {
-      if (!ReadBase128(file, &transform_length)) {
-        return OTS_FAILURE();
-      }
-    }
-    uint32_t src_length = transform_length;
-    if ((flag_byte >> 6) == 1 || (flag_byte >> 6) == 2) {
-      if (!ReadBase128(file, &src_length)) {
-        return OTS_FAILURE();
-      }
-    }
-    table->tag = tag;
-    table->flags = flags;
-    table->src_length = src_length;
-    table->transform_length = transform_length;
-    table->dst_length = dst_length;
-  }
-  return true;
-}
-
-}  // namespace
-
-namespace ots {
-
-size_t ComputeWOFF2FinalSize(const uint8_t* data, size_t length) {
-  ots::Buffer file(data, length);
-  uint32_t total_length;
-
-  if (!file.Skip(16) ||
-      !file.ReadU32(&total_length)) {
-    return 0;
-  }
-  return total_length;
-}
-
-bool ConvertWOFF2ToTTF(uint8_t* result, size_t result_length,
-                       const uint8_t* data, size_t length) {
-  static const uint32_t kWoff2Signature = 0x774f4632; // "wOF2"
-  ots::Buffer file(data, length);
-
-  uint32_t signature;
-  uint32_t flavor;
-  if (!file.ReadU32(&signature) || signature != kWoff2Signature ||
-      !file.ReadU32(&flavor)) {
-    return OTS_FAILURE();
-  }
-
-  // TODO(bashi): Should call IsValidVersionTag() here.
-
-  uint32_t reported_length;
-  if (!file.ReadU32(&reported_length) || length != reported_length) {
-    return OTS_FAILURE();
-  }
-  uint16_t num_tables;
-  if (!file.ReadU16(&num_tables) || !num_tables) {
-    return OTS_FAILURE();
-  }
-  // We don't care about these fields of the header:
-  //   uint16_t reserved
-  //   uint32_t total_sfnt_size
-  //   uint16_t major_version, minor_version
-  //   uint32_t meta_offset, meta_length, meta_orig_length
-  //   uint32_t priv_offset, priv_length
-  if (!file.Skip(30)) {
-    return OTS_FAILURE();
-  }
-  std::vector<Table> tables(num_tables);
-  // Note: change below to ReadLongDirectory to enable long format.
-  if (!ReadShortDirectory(&file, &tables, num_tables)) {
-    return OTS_FAILURE();
-  }
-  uint64_t src_offset = file.offset();
-  uint64_t dst_offset = kSfntHeaderSize +
-      kSfntEntrySize * static_cast<uint64_t>(num_tables);
-  uint64_t uncompressed_sum = 0;
-  for (uint16_t i = 0; i < num_tables; ++i) {
-    Table* table = &tables[i];
-    table->src_offset = src_offset;
-    src_offset += table->src_length;
-    if (src_offset > std::numeric_limits<uint32_t>::max()) {
-      return OTS_FAILURE();
-    }
-    src_offset = Round4(src_offset);  // TODO: reconsider
-    table->dst_offset = dst_offset;
-    dst_offset += table->dst_length;
-    if (dst_offset > std::numeric_limits<uint32_t>::max()) {
-      return OTS_FAILURE();
-    }
-    dst_offset = Round4(dst_offset);
-    if ((table->flags & kCompressionTypeMask) != kCompressionTypeNone) {
-      uncompressed_sum += table->src_length;
-      if (uncompressed_sum > std::numeric_limits<uint32_t>::max()) {
-        return OTS_FAILURE();
-      }
-    }
-  }
-  // Enforce same 30M limit on uncompressed tables as OTS
-  if (uncompressed_sum > 30 * 1024 * 1024) {
-    return OTS_FAILURE();
-  }
-  if (src_offset > length || dst_offset > result_length) {
-    return OTS_FAILURE();
-  }
-
-  const uint32_t sfnt_header_and_table_directory_size = 12 + 16 * num_tables;
-  if (sfnt_header_and_table_directory_size > result_length) {
-    return OTS_FAILURE();
-  }
-
-  // Start building the font
-  size_t offset = 0;
-  offset = StoreU32(result, offset, flavor);
-  offset = Store16(result, offset, num_tables);
-  unsigned max_pow2 = 0;
-  while (1u << (max_pow2 + 1) <= num_tables) {
-    max_pow2++;
-  }
-  const uint16_t output_search_range = (1u << max_pow2) << 4;
-  offset = Store16(result, offset, output_search_range);
-  offset = Store16(result, offset, max_pow2);
-  offset = Store16(result, offset, (num_tables << 4) - output_search_range);
-  for (uint16_t i = 0; i < num_tables; ++i) {
-    const Table* table = &tables[i];
-    offset = StoreU32(result, offset, table->tag);
-    offset = StoreU32(result, offset, 0);  // checksum, to fill in later
-    offset = StoreU32(result, offset, table->dst_offset);
-    offset = StoreU32(result, offset, table->dst_length);
-  }
-  std::vector<uint8_t> uncompressed_buf;
-  bool continue_valid = false;
-  for (uint16_t i = 0; i < num_tables; ++i) {
-    const Table* table = &tables[i];
-    uint32_t flags = table->flags;
-    const uint8_t* src_buf = data + table->src_offset;
-    uint32_t compression_type = flags & kCompressionTypeMask;
-    const uint8_t* transform_buf = NULL;
-    size_t transform_length = table->transform_length;
-    if ((flags & kWoff2FlagsContinueStream) != 0) {
-      if (!continue_valid) {
-        return OTS_FAILURE();
-      }
-    } else if (compression_type == kCompressionTypeNone) {
-      if (transform_length != table->src_length) {
-        return OTS_FAILURE();
-      }
-      transform_buf = src_buf;
-      continue_valid = false;
-    } else if ((flags & kWoff2FlagsContinueStream) == 0) {
-      uint64_t total_size = transform_length;
-      for (uint16_t j = i + 1; j < num_tables; ++j) {
-        if ((tables[j].flags & kWoff2FlagsContinueStream) == 0) {
-          break;
-        }
-        total_size += tables[j].transform_length;
-        if (total_size > std::numeric_limits<uint32_t>::max()) {
-          return OTS_FAILURE();
-        }
-      }
-      uncompressed_buf.resize(total_size);
-      if (!Woff2Uncompress(&uncompressed_buf[0], total_size,
-          src_buf, table->src_length, compression_type)) {
-        return OTS_FAILURE();
-      }
-      transform_buf = &uncompressed_buf[0];
-      continue_valid = true;
-    } else {
-      return OTS_FAILURE();
-    }
-
-    if ((flags & kWoff2FlagsTransform) == 0) {
-      if (transform_length != table->dst_length) {
-        return OTS_FAILURE();
-      }
-      if (static_cast<uint64_t>(table->dst_offset + transform_length) >
-          result_length) {
-        return OTS_FAILURE();
-      }
-      std::memcpy(result + table->dst_offset, transform_buf,
-          transform_length);
-    } else {
-      if (!ReconstructTransformed(tables, table->tag,
-            transform_buf, transform_length, result, result_length)) {
-        return OTS_FAILURE();
-      }
-    }
-    if (continue_valid) {
-      transform_buf += transform_length;
-      if (transform_buf > &uncompressed_buf[uncompressed_buf.size()]) {
-        return OTS_FAILURE();
-      }
-    }
-  }
-
-  return FixChecksums(tables, result);
-}
-
-}  // namespace ots
diff --git a/cpp/woff2.gyp b/cpp/woff2.gyp
deleted file mode 100644
index 6fd3dc9..0000000
--- a/cpp/woff2.gyp
+++ /dev/null
@@ -1,43 +0,0 @@
-{
-  'variables': {
-    'ots_include_dirs': [
-       # This isn't particularly elegant, but it works
-       '../ots-read-only/include',
-       '../ots-read-only/src',
-     ],
-  },
-  'target_defaults': {
-    'defines': [
-      'OTS_DEBUG',
-    ],
-  },
-  'targets': [
-    {
-      'target_name': 'woff2',
-      'type': 'static_library',
-      'sources': [
-        'woff2.cc',
-      ],
-      'include_dirs': [
-        '<@(ots_include_dirs)',
-      ],
-      'dependencies': [
-        '../ots-read-only/ots-standalone.gyp:ots',
-      ],
-    },
-    {
-      'target_name': 'woff2-decompress',
-      'type': 'executable',
-      'sources': [
-        'woff2-decompress.cc',
-      ],
-      'include_dirs': [
-        '<@(ots_include_dirs)',
-      ],
-      'dependencies': [
-        'woff2',
-      ],
-    },
-  ],
-}
-
diff --git a/cpp/woff2.h b/cpp/woff2.h
deleted file mode 100644
index 64ae6df..0000000
--- a/cpp/woff2.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2012 Google Inc. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef OTS_WOFF2_H_
-#define OTS_WOFF2_H_
-
-namespace ots {
-
-// Compute the size of the final uncompressed font, or 0 on error.
-size_t ComputeWOFF2FinalSize(const uint8_t *data, size_t length);
-
-// Decompresses the font into the target buffer. The result_length should
-// be the same as determined by ComputeFinalSize(). Returns true on successful
-// decompression.
-bool ConvertWOFF2ToTTF(uint8_t *result, size_t result_length,
-                  const uint8_t *data, size_t length);
-
-}
-
-#endif  // OTS_WOFF2_H_
diff --git a/lib/eotconverter.jar b/lib/eotconverter.jar
deleted file mode 100644
index 6543d70..0000000
--- a/lib/eotconverter.jar
+++ /dev/null
Binary files differ
diff --git a/lib/guava-11.0.1.jar b/lib/guava-11.0.1.jar
deleted file mode 100644
index af4a383..0000000
--- a/lib/guava-11.0.1.jar
+++ /dev/null
Binary files differ
diff --git a/lib/lzma.jar b/lib/lzma.jar
deleted file mode 100644
index 29a44e3..0000000
--- a/lib/lzma.jar
+++ /dev/null
Binary files differ
diff --git a/lib/sfntly.jar b/lib/sfntly.jar
deleted file mode 100644
index 415d5c5..0000000
--- a/lib/sfntly.jar
+++ /dev/null
Binary files differ
diff --git a/lib/woffconverter.jar b/lib/woffconverter.jar
deleted file mode 100644
index 1ac0133..0000000
--- a/lib/woffconverter.jar
+++ /dev/null
Binary files differ
diff --git a/src/com/google/typography/font/compression/AdvWidth.java b/src/com/google/typography/font/compression/AdvWidth.java
deleted file mode 100644
index 5bf67b5..0000000
--- a/src/com/google/typography/font/compression/AdvWidth.java
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2011 Google Inc. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package com.google.typography.font.compression;
-
-import com.google.typography.font.sfntly.Font;
-import com.google.typography.font.sfntly.Tag;
-import com.google.typography.font.sfntly.data.WritableFontData;
-import com.google.typography.font.sfntly.table.core.HorizontalMetricsTable;
-
-/**
- * Extract just advance widths from hmtx table.
- *
- * @author Raph Levien
- */
-public class AdvWidth {
-
-  public static WritableFontData encode(Font font) {
-    HorizontalMetricsTable hmtx = font.getTable(Tag.hmtx);
-    int nMetrics = hmtx.numberOfHMetrics();
-    WritableFontData result = WritableFontData.createWritableFontData(nMetrics * 2);
-    for (int i = 0; i < nMetrics; i++) {
-      result.writeShort(i * 2, hmtx.hMetricAdvanceWidth(i));
-    }
-    return result;
-  }
-}
diff --git a/src/com/google/typography/font/compression/CmapEncoder.java b/src/com/google/typography/font/compression/CmapEncoder.java
deleted file mode 100644
index 64888d6..0000000
--- a/src/com/google/typography/font/compression/CmapEncoder.java
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2011 Google Inc. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package com.google.typography.font.compression;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.typography.font.sfntly.Font;
-import com.google.typography.font.sfntly.Tag;
-import com.google.typography.font.sfntly.table.core.CMap;
-import com.google.typography.font.sfntly.table.core.CMapTable;
-import com.google.typography.font.sfntly.table.core.MaximumProfileTable;
-
-import java.io.ByteArrayOutputStream;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Experimental CMap encoder, based primarily on writing the _inverse_ encoding.
- *
- * @author Raph Levien
- */
-public class CmapEncoder {
-
-  public static byte[] encode(Font font) {
-    int nGlyphs = font.<MaximumProfileTable>getTable(Tag.maxp).numGlyphs();
-    CMapTable cmapTable = font.getTable(Tag.cmap);
-    CMap cmap = getBestCMap(cmapTable);
-    Map<Integer, Integer> invEncoding = Maps.newHashMap();
-    List<Integer> exceptions = Lists.newArrayList();
-    for (Integer i : cmap) {
-      int glyphId = cmap.glyphId(i);
-      if (invEncoding.containsKey(glyphId)) {
-        exceptions.add(i);
-        exceptions.add(glyphId);
-      } else {
-        invEncoding.put(glyphId, i);
-      }
-    }
-    ByteArrayOutputStream os = new ByteArrayOutputStream();
-    int last = -1;
-    for (int i = 0; i < nGlyphs; i++) {
-      if (invEncoding.containsKey(i)) {
-        int value = invEncoding.get(i);
-        int delta = value - last;
-        writeVShort(os, delta);
-        last = value;
-      } else {
-        writeVShort(os, 0);
-      }
-    }
-    for (int i : exceptions) {
-      writeVShort(os, i);
-    }
-    return os.toByteArray();
-  }
-
-  private static CMap getBestCMap(CMapTable cmapTable) {
-    for (CMap cmap : cmapTable) {
-      if (cmap.format() == CMap.CMapFormat.Format12.value()) {
-        return cmap;
-      }
-    }
-    for (CMap cmap : cmapTable) {
-      if (cmap.format() == CMap.CMapFormat.Format4.value()) {
-        return cmap;
-      }
-    }
-    return null;
-  }
-
-  // A simple signed varint encoding
-  static void writeVShort(ByteArrayOutputStream os, int value) {
-    if (value >= 0x2000 || value < -0x2000) {
-      os.write((byte)(0x80 | ((value >> 14) & 0x7f)));
-    }
-    if (value >= 0x40 || value < -0x40) {
-      os.write((byte)(0x80 | ((value >> 7) & 0x7f)));
-    }
-    os.write((byte)(value & 0x7f));
-  }
-}
diff --git a/src/com/google/typography/font/compression/CompressLzma.java b/src/com/google/typography/font/compression/CompressLzma.java
deleted file mode 100644
index 4bda54c..0000000
--- a/src/com/google/typography/font/compression/CompressLzma.java
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2012 Google Inc. All Rights Reserved.
-
-package com.google.typography.font.compression;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-
-import SevenZip.Compression.LZMA.Encoder;
-
-/**
- * @author Raph Levien
- * @author David Kuettel
- */
-public class CompressLzma {
-
-  public static byte[] compress(byte[] input) {
-    try {
-      ByteArrayInputStream in = new ByteArrayInputStream(input);
-      ByteArrayOutputStream out = new ByteArrayOutputStream();
-
-      Encoder encoder = new Encoder();
-      encoder.SetAlgorithm(2);
-      encoder.SetDictionarySize(1 << 23);
-      encoder.SetNumFastBytes(128);
-      encoder.SetMatchFinder(1);
-      encoder.SetLcLpPb(3, 0, 2);
-      encoder.SetEndMarkerMode(true);
-      encoder.WriteCoderProperties(out);
-      for (int i = 0; i < 8; i++) {
-        out.write((int) ((long) -1 >>> (8 * i)) & 0xFF);
-      }
-      encoder.Code(in, out, -1, -1, null);
-
-      out.flush();
-      out.close();
-
-      return out.toByteArray();
-    } catch (IOException e) {
-      throw new RuntimeException(e);
-    }
-  }
-}
diff --git a/src/com/google/typography/font/compression/CompressionRunner.java b/src/com/google/typography/font/compression/CompressionRunner.java
deleted file mode 100644
index 75d6370..0000000
--- a/src/com/google/typography/font/compression/CompressionRunner.java
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright 2011 Google Inc. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package com.google.typography.font.compression;
-
-import com.google.common.collect.Lists;
-import com.google.common.io.Files;
-import com.google.typography.font.sfntly.Font;
-import com.google.typography.font.sfntly.FontFactory;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.List;
-
-/**
- * A command-line tool for running different experimental compression code over
- * a corpus of fonts, and gathering statistics, particularly compression
- * efficiency.
- *
- * This is not intended to be production code.
- *
- * @author Raph Levien
- */
-public class CompressionRunner {
-
-  public static void main(String[] args) throws IOException {
-    boolean generateOutput = false;
-    List<String> descs = Lists.newArrayList();
-    String baseline = "gzip";
-
-    List<String> filenames = Lists.newArrayList();
-    for (int i = 0; i < args.length; i++) {
-      if (args[i].charAt(0) == '-') {
-        if (args[i].equals("-o")) {
-          generateOutput = true;
-        } else if (args[i].equals("-x")) {
-          descs.add(args[i + 1]);
-          i++;
-        } else if (args[i].equals("-b")) {
-          baseline = args[i + 1];
-          i++;
-        }
-      } else {
-        filenames.add(args[i]);
-      }
-    }
-
-    // String baseline = "glyf/triplet,code,push:lzma";
-    // String baseline = "glyf/cbbox,triplet,code,push:hdmx:lzma";
-    // descs.add("woff2");
-    if (descs.isEmpty()) {
-      descs.add("glyf/cbbox,triplet,code,reslice:woff2/lzma");
-    }
-    run(filenames, baseline, descs, generateOutput);
-  }
-
-  private static void run(List<String> filenames, String baseline, List<String> descs,
-                          boolean generateOutput) throws IOException {
-    PrintWriter o = new PrintWriter(System.out);
-    List<StatsCollector> stats = Lists.newArrayList();
-    for (int i = 0; i < descs.size(); i++) {
-      stats.add(new StatsCollector());
-    }
-    FontFactory fontFactory = FontFactory.getInstance();
-    o.println("<html>");
-    for (String filename : filenames) {
-      byte[] bytes = Files.toByteArray(new File(filename));
-      Font font = fontFactory.loadFonts(bytes)[0];
-      byte[] baselineResult = Experiment.run(font, baseline);
-      o.printf("<!-- %s: baseline %d bytes", new File(filename).getName(), baselineResult.length);
-      for (int i = 0; i < descs.size(); i++) {
-        byte[] expResult = Experiment.run(font, descs.get(i));
-        if (generateOutput) {
-          String newFilename = filename;
-          if (newFilename.endsWith(".ttf")) {
-            newFilename = newFilename.substring(0, newFilename.length() - 4);
-          }
-          newFilename += ".woff2";
-          Files.write(expResult, new File(newFilename));
-        }
-        double percent = 100. * expResult.length / baselineResult.length;
-        stats.get(i).addStat(percent);
-        o.printf(", %c %.2f%%", 'A' + i, percent);
-      }
-      o.printf(" -->\n");
-    }
-    stats.get(0).chartHeader(o, descs.size());
-    for (int i = 0; i < descs.size(); i++) {
-      stats.get(i).chartData(o, i + 1);
-    }
-    stats.get(0).chartEnd(o);
-    o.printf("<p>baseline: %s</p>\n", baseline);
-    for (int i = 0; i < descs.size(); i++) {
-      StatsCollector sc = stats.get(i);
-      o.printf("<p>%c: %s: median %f, mean %f</p>\n",
-          'A' + i, descs.get(i), sc.median(), sc.mean());
-    }
-    stats.get(0).chartFooter(o);
-    o.close();
-  }
-}
diff --git a/src/com/google/typography/font/compression/CompressionStats.java b/src/com/google/typography/font/compression/CompressionStats.java
deleted file mode 100644
index 9b5caee..0000000
--- a/src/com/google/typography/font/compression/CompressionStats.java
+++ /dev/null
@@ -1,105 +0,0 @@
-package com.google.typography.font.compression;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Compression stats, both aggregate and per font.
- *
- * @author David Kuettel
- */
-public class CompressionStats {
-
-  public enum Size { ORIGINAL, GZIP, WOFF, WOFF2 }
-
-  private final List<Stats> values = Lists.newArrayList();
-
-  public void add(Stats stat) {
-    values.add(stat);
-  }
-
-  public List<Stats> values() {
-    return values;
-  }
-
-  public double mean(Size size) {
-    double sum = 0;
-    for (Long value : values(size)) {
-      sum += value;
-    }
-    return sum / values.size();
-  }
-
-  public double median(Size size) {
-    List<Long> list = values(size);
-    Collections.sort(list);
-    int length = list.size();
-    if (length % 2 == 1) {
-      return list.get((length - 1) / 2);
-    } else {
-      return 0.5 * (list.get(length / 2 - 1) + list.get(length / 2));
-    }
-  }
-
-  private List<Long> values(Size size) {
-    List<Long> list = Lists.newArrayList();
-    for (Stats stats : values) {
-      list.add(stats.getSize(size));
-    }
-    return list;
-  }
-
-  public static class Stats {
-
-    private final String filename;
-    private final Map<Size, Long> sizes;
-
-    private Stats(String filename, Map<Size, Long> sizes) {
-      this.filename = filename;
-      this.sizes = sizes;
-    }
-
-    public String getFilename() {
-      return filename;
-    }
-
-    public long getSize(Size size) {
-      return sizes.get(size);
-    }
-
-    public double getPercent(Size s1, Size s2) {
-      long v1 = sizes.get(s1);
-      long v2 = sizes.get(s2);
-      return 100.0 * (v1 - v2) / v1;
-    }
-
-    public static Builder builder() {
-      return new Builder();
-    }
-
-    public static class Builder {
-
-      private String filename;
-      private Map<Size, Long> sizes = Maps.newHashMap();
-
-      public Builder setFilename(String filename) {
-        this.filename = filename;
-        return this;
-      }
-
-      public Builder setSize(Size key, long value) {
-        this.sizes.put(key, value);
-        return this;
-      }
-
-      public Stats build() {
-        return new Stats(filename, ImmutableMap.copyOf(sizes));
-      }
-    }
-  }
-}
diff --git a/src/com/google/typography/font/compression/CsvReport.java b/src/com/google/typography/font/compression/CsvReport.java
deleted file mode 100644
index 4125a23..0000000
--- a/src/com/google/typography/font/compression/CsvReport.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package com.google.typography.font.compression;
-
-import com.google.common.io.Closeables;
-
-import java.io.BufferedWriter;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.PrintWriter;
-
-/**
- * Generates a CSV report containing the compression stats.
- *
- * @author David Kuettel
- */
-public class CsvReport {
-
-  public static void create(CompressionStats stats, String filename) throws IOException {
-    PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(filename)));
-    try {
-      writer.printf("Font, Original (bytes), WOFF 1.0 (bytes), WOFF 2.0 (bytes), %% Improvement\n");
-      for (CompressionStats.Stats stat : stats.values()) {
-        writer.printf("%s, %d, %d, %d, %.2f%%\n",
-            stat.getFilename(),
-            stat.getSize(CompressionStats.Size.ORIGINAL),
-            stat.getSize(CompressionStats.Size.WOFF),
-            stat.getSize(CompressionStats.Size.WOFF2),
-            stat.getPercent(CompressionStats.Size.WOFF, CompressionStats.Size.WOFF2));
-      }
-    } finally {
-      Closeables.closeQuietly(writer);
-    }
-  }
-}
diff --git a/src/com/google/typography/font/compression/Experiment.java b/src/com/google/typography/font/compression/Experiment.java
deleted file mode 100644
index a5e97e9..0000000
--- a/src/com/google/typography/font/compression/Experiment.java
+++ /dev/null
@@ -1,93 +0,0 @@
-package com.google.typography.font.compression;
-
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Sets;
-import com.google.typography.font.sfntly.Font;
-import com.google.typography.font.sfntly.FontFactory;
-import com.google.typography.font.sfntly.Tag;
-import com.google.typography.font.tools.conversion.eot.EOTWriter;
-import com.google.typography.font.tools.conversion.woff.WoffWriter;
-
-import java.io.IOException;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * @author Raph Levien
- */
-public class Experiment {
-
-  /**
-   * Does one experimental compression on a font, using the string to guide what
-   * gets done.
-   *
-   * @param srcFont Source font
-   * @param desc experiment description string; the exact format is probably
-   *        still evolving
-   * @return serialization of compressed font
-   * @throws IOException
-   */
-  public static byte[] run(Font srcFont, String desc) throws IOException {
-    Font font = srcFont;
-    FontFactory fontFactory = FontFactory.getInstance();
-    String[] pieces = desc.split(":");
-    boolean keepDsig = false;
-
-    for (int i = 0; i < pieces.length - 1; i++) {
-      String[] piece = pieces[i].split("/");
-      String cmd = piece[0];
-      if (cmd.equals("glyf")) {
-        font = FontUtil.preprocessMtxGlyf(font, piece.length > 1 ? piece[1] : "").build();
-      } else if (cmd.equals("hmtx")) {
-        font = FontUtil.preprocessHmtx(font).build();
-      } else if (cmd.equals("hdmx")) {
-        font = FontUtil.preprocessHdmx(font).build();
-      } else if (cmd.equals("cmap")) {
-        font = FontUtil.preprocessCmap(font).build();
-      } else if (cmd.equals("kern")) {
-        font = FontUtil.preprocessKern(font).build();
-      } else if (cmd.equals("keepdsig")) {
-        keepDsig = true;
-      } else if (cmd.equals("strip")) {
-        Set<Integer> removeTags = Sets.newTreeSet();
-        for (String tag : piece[1].split(",")) {
-          removeTags.add(Tag.intValue(tag.getBytes()));
-        }
-        font = FontUtil.stripTags(font, removeTags).build();
-      }
-    }
-    if (!keepDsig) {
-      font = FontUtil.stripTags(font, ImmutableSet.of(Tag.DSIG)).build();
-    }
-
-    String last = pieces[pieces.length - 1];
-    String[] lastPieces = last.split("/");
-    String lastBase = lastPieces[0];
-    String lastArgs = lastPieces.length > 1 ? lastPieces[1] : "";
-    if (!lastBase.equals("woff2")) {
-      Set<Integer> tagsToStrip = Sets.newHashSet();
-      for (Map.Entry<Integer, Integer> mapping : Woff2Writer.getTransformMap().entrySet()) {
-        if (font.hasTable(mapping.getValue())) {
-          tagsToStrip.add(mapping.getKey());
-        }
-      }
-      font = FontUtil.stripTags(font, tagsToStrip).build();
-    }
-
-    byte[] result = null;
-    if (lastBase.equals("gzip")) {
-      result = GzipUtil.deflate(FontUtil.toBytes(fontFactory, font));
-    } else if (lastBase.equals("lzma")) {
-      result = CompressLzma.compress(FontUtil.toBytes(fontFactory, font));
-    } else if (lastBase.equals("woff")) {
-      result = FontUtil.toBytes(new WoffWriter().convert(font));
-    } else if (lastBase.equals("woff2")) {
-      result = FontUtil.toBytes(new Woff2Writer(lastArgs).convert(font));
-    } else if (lastBase.equals("eot")) {
-      result = FontUtil.toBytes(new EOTWriter(true).convert(font));
-    } else if (lastBase.equals("uncomp")) {
-      result = FontUtil.toBytes(fontFactory, font);
-    }
-    return result;
-  }
-}
diff --git a/src/com/google/typography/font/compression/FontUtil.java b/src/com/google/typography/font/compression/FontUtil.java
deleted file mode 100644
index 155a042..0000000
--- a/src/com/google/typography/font/compression/FontUtil.java
+++ /dev/null
@@ -1,100 +0,0 @@
-package com.google.typography.font.compression;
-
-import com.google.common.collect.ImmutableSet;
-import com.google.typography.font.sfntly.Font;
-import com.google.typography.font.sfntly.FontFactory;
-import com.google.typography.font.sfntly.Tag;
-import com.google.typography.font.sfntly.data.ReadableFontData;
-import com.google.typography.font.tools.conversion.eot.HdmxEncoder;
-
-import java.io.ByteArrayOutputStream;
-import java.util.Arrays;
-import java.util.Set;
-
-/**
- * Font utility methods
- *
- * @author Raph Levien
- */
-public class FontUtil {
-
-  public static Font.Builder stripTags(Font srcFont, Set<Integer> removeTags) {
-    FontFactory fontFactory = FontFactory.getInstance();
-    Font.Builder fontBuilder = fontFactory.newFontBuilder();
-
-    for (Integer tag : srcFont.tableMap().keySet()) {
-      if (!removeTags.contains(tag)) {
-        fontBuilder.newTableBuilder(tag, srcFont.getTable(tag).readFontData());
-      }
-    }
-    return fontBuilder;
-  }
-
-  public static Font.Builder preprocessMtxGlyf(Font srcFont, String options) {
-    Font.Builder fontBuilder = stripTags(srcFont, ImmutableSet.<Integer>of());
-    GlyfEncoder glyfEncoder = new GlyfEncoder(options);
-    glyfEncoder.encode(srcFont);
-    addTableBytes(fontBuilder, Tag.intValue(new byte[]{'g', 'l', 'z', '1'}),
-        glyfEncoder.getGlyfBytes());
-    addTableBytes(fontBuilder, Tag.intValue(new byte[] {'l', 'o', 'c', 'z'}),
-        glyfEncoder.getLocaBytes());
-    if (!Arrays.asList(options.split(",")).contains("reslice")) {
-      addTableBytes(fontBuilder, Tag.intValue(new byte[] {'g', 'l', 'z', '2'}),
-          glyfEncoder.getCodeBytes());
-      addTableBytes(fontBuilder, Tag.intValue(new byte[] {'g', 'l', 'z', '3'}),
-          glyfEncoder.getPushBytes());
-    }
-    return fontBuilder;
-  }
-
-  public static Font.Builder preprocessHmtx(Font srcFont) {
-    Font.Builder fontBuilder = stripTags(srcFont, ImmutableSet.of(Tag.hmtx));
-    addTableBytes(fontBuilder, Tag.intValue(new byte[] {'h', 'm', 't', 'z'}),
-        toBytes(AdvWidth.encode(srcFont)));
-    return fontBuilder;
-  }
-
-  public static Font.Builder preprocessHdmx(Font srcFont) {
-    Font.Builder fontBuilder = stripTags(srcFont, ImmutableSet.of(Tag.hdmx));
-    if (srcFont.hasTable(Tag.hdmx)) {
-      addTableBytes(fontBuilder, Tag.hdmx, toBytes(new HdmxEncoder().encode(srcFont)));
-    }
-    return fontBuilder;
-  }
-
-  public static Font.Builder preprocessCmap(Font srcFont) {
-    Font.Builder fontBuilder = stripTags(srcFont, ImmutableSet.of(Tag.cmap));
-    addTableBytes(fontBuilder, Tag.intValue(new byte[] {'c', 'm', 'a', 'z'}),
-        CmapEncoder.encode(srcFont));
-    return fontBuilder;
-  }
-
-  public static Font.Builder preprocessKern(Font srcFont) {
-    Font.Builder fontBuilder = stripTags(srcFont, ImmutableSet.of(Tag.kern));
-    if (srcFont.hasTable(Tag.kern)) {
-      addTableBytes(fontBuilder, Tag.intValue(new byte[] {'k', 'e', 'r', 'z'}),
-          toBytes(KernEncoder.encode(srcFont)));
-    }
-    return fontBuilder;
-  }
-
-  public static void addTableBytes(Font.Builder fontBuilder, int tag, byte[] contents) {
-    fontBuilder.newTableBuilder(tag, ReadableFontData.createReadableFontData(contents));
-  }
-
-  public static byte[] toBytes(FontFactory fontFactory, Font font) {
-    try {
-      ByteArrayOutputStream baos = new ByteArrayOutputStream();
-      fontFactory.serializeFont(font, baos);
-      return baos.toByteArray();
-    } catch (Exception e) {
-      throw new RuntimeException(e);
-    }
-  }
-
-  public static byte[] toBytes(ReadableFontData rfd) {
-    byte[] result = new byte[rfd.length()];
-    rfd.readBytes(0, result, 0, rfd.length());
-    return result;
-  }
-}
diff --git a/src/com/google/typography/font/compression/GlyfEncoder.java b/src/com/google/typography/font/compression/GlyfEncoder.java
deleted file mode 100644
index 1144ee1..0000000
--- a/src/com/google/typography/font/compression/GlyfEncoder.java
+++ /dev/null
@@ -1,481 +0,0 @@
-// Copyright 2011 Google Inc. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package com.google.typography.font.compression;
-
-import com.google.typography.font.sfntly.Font;
-import com.google.typography.font.sfntly.Tag;
-import com.google.typography.font.sfntly.data.ReadableFontData;
-import com.google.typography.font.sfntly.table.core.FontHeaderTable;
-import com.google.typography.font.sfntly.table.truetype.CompositeGlyph;
-import com.google.typography.font.sfntly.table.truetype.Glyph;
-import com.google.typography.font.sfntly.table.truetype.GlyphTable;
-import com.google.typography.font.sfntly.table.truetype.LocaTable;
-import com.google.typography.font.sfntly.table.truetype.SimpleGlyph;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Implementation of compression of CTF glyph data, as per sections 5.6-5.10 and 6 of the spec.
- * This is a hacked-up version with a number of options, for experimenting.
- *
- * @author Raph Levien
- */
-public class GlyfEncoder {
-
-  private final ByteArrayOutputStream nContourStream;
-  private final ByteArrayOutputStream nPointsStream;
-  private final ByteArrayOutputStream flagBytesStream;
-  private final ByteArrayOutputStream compositeStream;
-  private final ByteArrayOutputStream bboxStream;
-  private final ByteArrayOutputStream glyfStream;
-  private final ByteArrayOutputStream pushStream;
-  private final ByteArrayOutputStream codeStream;
-  private final boolean sbbox;
-  private final boolean cbbox;
-  private final boolean code;
-  private final boolean triplet;
-  private final boolean doPush;
-  private final boolean doHop;
-  private final boolean push2byte;
-  private final boolean reslice;
-
-  private int nGlyphs;
-  private byte[] bboxBitmap;
-  private FontHeaderTable.IndexToLocFormat indexFmt;
-
-  public GlyfEncoder(String options) {
-    glyfStream = new ByteArrayOutputStream();
-    pushStream = new ByteArrayOutputStream();
-    codeStream = new ByteArrayOutputStream();
-    nContourStream = new ByteArrayOutputStream();
-    nPointsStream = new ByteArrayOutputStream();
-    flagBytesStream = new ByteArrayOutputStream();
-    compositeStream = new ByteArrayOutputStream();
-    bboxStream = new ByteArrayOutputStream();
-    boolean sbbox = false;
-    boolean cbbox = false;
-    boolean code = false;
-    boolean triplet = false;
-    boolean doPush = false;
-    boolean reslice = false;
-    boolean doHop = false;
-    boolean push2byte = false;
-    for (String option : options.split(",")) {
-      if (option.equals("sbbox")) {
-        sbbox = true;
-      } else if (option.equals("cbbox")) {
-        cbbox = true;
-      } else if (option.equals("code")) {
-        code = true;
-      } else if (option.equals("triplet")) {
-        triplet = true;
-      } else if (option.equals("push")) {
-        doPush = true;
-      } else if (option.equals("hop")) {
-        doHop = true;
-      } else if (option.equals("push2byte")) {
-        push2byte = true;
-      } else if (option.equals("reslice")) {
-        reslice = true;
-      }
-    }
-    this.sbbox = sbbox;
-    this.cbbox = cbbox;
-    this.code = code;
-    this.triplet = triplet;
-    this.doPush = doPush;
-    this.doHop = doHop;
-    this.push2byte = push2byte;
-    this.reslice = reslice;
-  }
-
-  public void encode(Font sourceFont) {
-    FontHeaderTable head = sourceFont.getTable(Tag.head);
-    indexFmt = head.indexToLocFormat();
-    LocaTable loca = sourceFont.getTable(Tag.loca);
-    nGlyphs = loca.numGlyphs();
-    GlyphTable glyf = sourceFont.getTable(Tag.glyf);
-    bboxBitmap = new byte[((nGlyphs + 31) >> 5) << 2];
-
-    for (int glyphId = 0; glyphId < nGlyphs; glyphId++) {
-      int sourceOffset = loca.glyphOffset(glyphId);
-      int length = loca.glyphLength(glyphId);
-      Glyph glyph = glyf.glyph(sourceOffset, length);
-      writeGlyph(glyphId, glyph);
-    }
-  }
-
-  private void writeGlyph(int glyphId, Glyph glyph) {
-    try {
-      if (glyph == null || glyph.dataLength() == 0) {
-        writeNContours(0);
-      } else if (glyph instanceof SimpleGlyph) {
-        writeSimpleGlyph(glyphId, (SimpleGlyph)glyph);
-      } else if (glyph instanceof CompositeGlyph) {
-        writeCompositeGlyph(glyphId, (CompositeGlyph)glyph);
-      }
-    } catch (IOException e) {
-      throw new RuntimeException("unexpected IOException writing glyph data", e);
-    }
-  }
-
-  private void writeInstructions(Glyph glyph) throws IOException{
-    if (doPush) {
-      splitPush(glyph);
-    } else {
-      int pushCount = 0;
-      int codeSize = glyph.instructionSize();
-      if (!reslice) {
-        write255UShort(glyfStream, pushCount);
-      }
-      write255UShort(glyfStream, codeSize);
-      if (codeSize > 0) {
-        if (code) {
-          glyph.instructions().copyTo(codeStream);
-        } else {
-          glyph.instructions().copyTo(glyfStream);
-        }
-      }
-    }
-  }
-
-  private void writeSimpleGlyph(int glyphId, SimpleGlyph glyph) throws IOException {
-    int numContours = glyph.numberOfContours();
-    writeNContours(numContours);
-    if (sbbox) {
-      writeBbox(glyphId, glyph);
-    }
-    // TODO: check that bbox matches, write bbox if not
-    for (int i = 0; i < numContours; i++) {
-      if (reslice) {
-        write255UShort(nPointsStream, glyph.numberOfPoints(i));
-      } else {
-        write255UShort(glyfStream, glyph.numberOfPoints(i) - (i == 0 ? 1 : 0));
-      }
-    }
-    ByteArrayOutputStream os = new ByteArrayOutputStream();
-    int lastX = 0;
-    int lastY = 0;
-    for (int i = 0; i < numContours; i++) {
-      int numPoints = glyph.numberOfPoints(i);
-      for (int j = 0; j < numPoints; j++) {
-        int x = glyph.xCoordinate(i, j);
-        int y = glyph.yCoordinate(i, j);
-        int dx = x - lastX;
-        int dy = y - lastY;
-        if (triplet) {
-          writeTriplet(os, glyph.onCurve(i, j), dx, dy);
-        } else {
-          writeVShort(os, dx * 2 + (glyph.onCurve(i, j) ? 1 : 0));
-          writeVShort(os, dy);
-        }
-        lastX = x;
-        lastY = y;
-      }
-    }
-    os.writeTo(glyfStream);
-    if (numContours > 0) {
-      writeInstructions(glyph);
-    }
-  }
-
-  private void writeCompositeGlyph(int glyphId, CompositeGlyph glyph) throws IOException {
-    boolean haveInstructions = false;
-    writeNContours(-1);
-    if (cbbox) {
-      writeBbox(glyphId, glyph);
-    }
-    ByteArrayOutputStream outStream = reslice ? compositeStream : glyfStream;
-    for (int i = 0; i < glyph.numGlyphs(); i++) {
-      int flags = glyph.flags(i);
-      writeUShort(outStream, flags);
-      haveInstructions = (flags & CompositeGlyph.FLAG_WE_HAVE_INSTRUCTIONS) != 0;
-      writeUShort(outStream, glyph.glyphIndex(i));
-      if ((flags & CompositeGlyph.FLAG_ARG_1_AND_2_ARE_WORDS) == 0) {
-        outStream.write(glyph.argument1(i));
-        outStream.write(glyph.argument2(i));
-      } else {
-        writeUShort(outStream, glyph.argument1(i));
-        writeUShort(outStream, glyph.argument2(i));
-      }
-      if (glyph.transformationSize(i) != 0) {
-        try {
-          outStream.write(glyph.transformation(i));
-        } catch (IOException e) {
-        }
-      }
-    }
-    if (haveInstructions) {
-      writeInstructions(glyph);
-    }
-  }
-
-  private void writeNContours(int nContours) {
-    if (reslice) {
-      writeUShort(nContourStream, nContours);
-    } else {
-      writeUShort(nContours);
-    }
-  }
-
-  private void writeBbox(int glyphId, Glyph glyph) {
-    if (reslice) {
-      bboxBitmap[glyphId >> 3] |= 0x80 >> (glyphId & 7);
-    }
-    ByteArrayOutputStream outStream = reslice ? bboxStream : glyfStream;
-    writeUShort(outStream, glyph.xMin());
-    writeUShort(outStream, glyph.yMin());
-    writeUShort(outStream, glyph.xMax());
-    writeUShort(outStream, glyph.yMax());
-  }
-
-  private void writeUShort(ByteArrayOutputStream os, int value) {
-    os.write(value >> 8);
-    os.write(value & 255);
-  }
-
-  private void writeUShort(int value) {
-    writeUShort(glyfStream, value);
-  }
-
-  private void writeLong(OutputStream os, int value) throws IOException {
-    os.write((value >> 24) & 255);
-    os.write((value >> 16) & 255);
-    os.write((value >> 8) & 255);
-    os.write(value & 255);
-  }
-
-  // As per 6.1.1 of spec
-  // visible for testing
-  static void write255UShort(ByteArrayOutputStream os, int value) {
-    if (value < 0) {
-      throw new IllegalArgumentException();
-    }
-    if (value < 253) {
-      os.write((byte)value);
-    } else if (value < 506) {
-      os.write(255);
-      os.write((byte)(value - 253));
-    } else if (value < 762) {
-      os.write(254);
-      os.write((byte)(value - 506));
-    } else {
-      os.write(253);
-      os.write((byte)(value >> 8));
-      os.write((byte)(value & 0xff));
-    }
-  }
-
-  // As per 6.1.1 of spec
-  // visible for testing
-  static void write255Short(OutputStream os, int value) throws IOException {
-    int absValue = Math.abs(value);
-    if (value < 0) {
-      // spec is unclear about whether words should be signed. This code is conservative, but we
-      // can test once the implementation is working.
-      os.write(250);
-    }
-    if (absValue < 250) {
-      os.write((byte)absValue);
-    } else if (absValue < 500) {
-      os.write(255);
-      os.write((byte)(absValue - 250));
-    } else if (absValue < 756) {
-      os.write(254);
-      os.write((byte)(absValue - 500));
-    } else {
-      os.write(253);
-      os.write((byte)(absValue >> 8));
-      os.write((byte)(absValue & 0xff));
-    }
-  }
-
-  // A simple signed varint encoding
-  static void writeVShort(ByteArrayOutputStream os, int value) {
-    if (value >= 0x2000 || value < -0x2000) {
-      os.write((byte)(0x80 | ((value >> 14) & 0x7f)));
-    }
-    if (value >= 0x40 || value < -0x40) {
-      os.write((byte)(0x80 | ((value >> 7) & 0x7f)));
-    }
-    os.write((byte)(value & 0x7f));
-  }
-
-  // As in section 5.11 of the spec
-  // visible for testing
-  void writeTriplet(OutputStream os, boolean onCurve, int x, int y) throws IOException {
-    int absX = Math.abs(x);
-    int absY = Math.abs(y);
-    int onCurveBit = onCurve ? 0 : 128;
-    int xSignBit = (x < 0) ? 0 : 1;
-    int ySignBit = (y < 0) ? 0 : 1;
-    int xySignBits = xSignBit + 2 * ySignBit;
-    ByteArrayOutputStream flagStream = reslice ? flagBytesStream : glyfStream;
-
-    if (x == 0 && absY < 1280) {
-      flagStream.write(onCurveBit + ((absY & 0xf00) >> 7) + ySignBit);
-      os.write(absY & 0xff);
-    } else if (y == 0 && absX < 1280) {
-      flagStream.write(onCurveBit + 10 + ((absX & 0xf00) >> 7) + xSignBit);
-      os.write(absX & 0xff);
-    } else if (absX < 65 && absY < 65) {
-      flagStream.write(onCurveBit + 20 + ((absX - 1) & 0x30) + (((absY - 1) & 0x30) >> 2) +
-          xySignBits);
-      os.write((((absX - 1) & 0xf) << 4) | ((absY - 1) & 0xf));
-    } else if (absX < 769 && absY < 769) {
-      flagStream.write(onCurveBit + 84 + 12 * (((absX - 1) & 0x300) >> 8) +
-          (((absY - 1) & 0x300) >> 6) + xySignBits);
-      os.write((absX - 1) & 0xff);
-      os.write((absY - 1) & 0xff);
-    } else if (absX < 4096 && absY < 4096) {
-      flagStream.write(onCurveBit + 120 + xySignBits);
-      os.write(absX >> 4);
-      os.write(((absX & 0xf) << 4) | (absY >> 8));
-      os.write(absY & 0xff);
-    } else {
-      flagStream.write(onCurveBit + 124 + xySignBits);
-      os.write(absX >> 8);
-      os.write(absX & 0xff);
-      os.write(absY >> 8);
-      os.write(absY & 0xff);
-    }
-  }
-
-  /**
-   * Split the instructions into a push sequence and the remainder of the instructions.
-   * Writes both streams, and the counts to the glyfStream.
-   *
-   * @param glyph
-   */
-  private void splitPush(Glyph glyph) throws IOException {
-    int instrSize = glyph.instructionSize();
-    ReadableFontData data = glyph.instructions();
-    int i = 0;
-    List<Integer> result = new ArrayList<Integer>();
-    // All push sequences are at least two bytes, make sure there's enough room
-    while (i + 1 < instrSize) {
-      int ix = i;
-      int instr = data.readUByte(ix++);
-      int n = 0;
-      int size = 0;
-      if (instr == 0x40 || instr == 0x41) {
-        // NPUSHB, NPUSHW
-        n = data.readUByte(ix++);
-        size = (instr & 1) + 1;
-      } else if (instr >= 0xB0 && instr < 0xC0) {
-        // PUSHB, PUSHW
-        n = 1 + (instr & 7);
-        size = ((instr & 8) >> 3) + 1;
-      } else {
-        break;
-      }
-      if (i + size * n > instrSize) {
-        // This is a broken font, and a potential buffer overflow, but in the interest
-        // of preserving the original, we just put the broken instruction sequence in
-        // the stream.
-        break;
-      }
-      for (int j = 0; j < n; j++) {
-        if (size == 1) {
-          result.add(data.readUByte(ix));
-        } else {
-          result.add(data.readShort(ix));
-        }
-        ix += size;
-      }
-      i = ix;
-    }
-    int pushCount = result.size();
-    int codeSize = instrSize - i;
-    write255UShort(glyfStream, pushCount);
-    write255UShort(glyfStream, codeSize);
-    encodePushSequence(pushStream, result);
-    if (codeSize > 0) {
-      data.slice(i).copyTo(codeStream);
-    }
-  }
-
-  // As per section 6.2.2 of the spec
-  private void encodePushSequence(ByteArrayOutputStream os, List<Integer> data) throws IOException {
-    int n = data.size();
-    int hopSkip = 0;
-    for (int i = 0; i < n; i++) {
-      if ((hopSkip & 1) == 0) {
-        int val = data.get(i);
-        if (doHop && hopSkip == 0 && i >= 2 &&
-            i + 2 < n && val == data.get(i - 2) && val == data.get(i + 2)) {
-          if (i + 4 < n && val == data.get(i + 4)) {
-            // Hop4 code
-            os.write(252);
-            hopSkip = 0x14;
-          } else {
-            // Hop3 code
-            os.write(251);
-            hopSkip = 4;
-          }
-        } else {
-          if (push2byte) {
-            // Measure relative effectiveness of 255Short literal encoding vs 2-byte ushort.
-            writeUShort(os, data.get(i));
-          } else {
-            write255Short(os, data.get(i));
-          }
-        }
-      }
-      hopSkip >>= 1;
-    }
-  }
-
-  public byte[] getGlyfBytes() {
-    if (reslice) {
-      ByteArrayOutputStream newStream = new ByteArrayOutputStream();
-      try {
-        // Pack all the glyf streams in a sensible way
-        writeLong(newStream, 0);  // version
-        writeUShort(newStream, nGlyphs);
-        writeUShort(newStream, indexFmt.value());
-        writeLong(newStream, nContourStream.size());
-        writeLong(newStream, nPointsStream.size());
-        writeLong(newStream, flagBytesStream.size());
-        writeLong(newStream, glyfStream.size());
-        writeLong(newStream, compositeStream.size());
-        writeLong(newStream, bboxBitmap.length + bboxStream.size());
-        writeLong(newStream, codeStream.size());
-//        System.out.printf("stream sizes = %d %d %d %d %d %d %d\n",
-//            nContourStream.size(), nPointsStream.size(), flagBytesStream.size(), glyfStream.size(),
-//            compositeStream.size(), bboxStream.size(), codeStream.size());
-        nContourStream.writeTo(newStream);
-        nPointsStream.writeTo(newStream);
-        flagBytesStream.writeTo(newStream);
-        glyfStream.writeTo(newStream);
-        compositeStream.writeTo(newStream);
-        newStream.write(bboxBitmap);
-        bboxStream.writeTo(newStream);
-        codeStream.writeTo(newStream);
-      } catch (IOException e) {
-        throw new RuntimeException("Can't happen, world must have come to end", e);
-      }
-      return newStream.toByteArray();
-    } else {
-      return glyfStream.toByteArray();
-    }
-  }
-
-  public byte[] getPushBytes() {
-    return pushStream.toByteArray();
-  }
-
-  public byte[] getCodeBytes() {
-    return codeStream.toByteArray();
-  }
-
-  public byte[] getLocaBytes() {
-    return new byte[]{ };
-  }
-}
diff --git a/src/com/google/typography/font/compression/GzipUtil.java b/src/com/google/typography/font/compression/GzipUtil.java
deleted file mode 100644
index 75fac1b..0000000
--- a/src/com/google/typography/font/compression/GzipUtil.java
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2011 Google Inc. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package com.google.typography.font.compression;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.util.zip.Deflater;
-import java.util.zip.DeflaterOutputStream;
-
-/**
- * Simple utility for GZIP compression
- *
- * @author Raph Levien
- */
-public class GzipUtil {
-
-  public static byte[] deflate(byte[] bytes) {
-    try {
-      ByteArrayOutputStream baos = new ByteArrayOutputStream();
-      DeflaterOutputStream dos = new DeflaterOutputStream(baos, new Deflater());
-      dos.write(bytes, 0, bytes.length);
-      dos.close();
-      return baos.toByteArray();
-    } catch (IOException e) {
-      throw new RuntimeException(e);
-    }
-  }
-}
-
diff --git a/src/com/google/typography/font/compression/KernEncoder.java b/src/com/google/typography/font/compression/KernEncoder.java
deleted file mode 100644
index 7d94ccb..0000000
--- a/src/com/google/typography/font/compression/KernEncoder.java
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2011 Google Inc. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package com.google.typography.font.compression;
-
-import com.google.typography.font.sfntly.Font;
-import com.google.typography.font.sfntly.Tag;
-import com.google.typography.font.sfntly.data.ReadableFontData;
-import com.google.typography.font.sfntly.data.WritableFontData;
-import com.google.typography.font.sfntly.table.Table;
-
-/**
- * Encoder for "kern" table. This probably won't go in the spec because an even more
- * effective technique would be to do class kerning in the GDEF tables, but, even so, I wanted
- * to capture the stats.
- *
- * @author Raph Levien
- */
-public class KernEncoder {
-
-  public static WritableFontData encode(Font font) {
-    Table kernTable = font.getTable(Tag.kern);
-    ReadableFontData data = kernTable.readFontData();
-    WritableFontData newData = WritableFontData.createWritableFontData(data.size());
-    data.copyTo(newData);
-    if (data.readUShort(0) == 0 && data.readUShort(4) == 0) {
-      int base = 18;
-      int nPairs = data.readUShort(10);
-      for (int i = 0; i < nPairs; i++) {
-        newData.writeUShort(base + i * 2, data.readUShort(base + i * 6));
-        newData.writeUShort(base + nPairs * 2 + i * 2, data.readUShort(base + i * 6 + 2));
-        newData.writeUShort(base + nPairs * 4 + i * 2, data.readUShort(base + i * 6 + 4));
-      }
-    }
-    return newData;
-  }
-}
diff --git a/src/com/google/typography/font/compression/SimpleRunner.java b/src/com/google/typography/font/compression/SimpleRunner.java
deleted file mode 100644
index 43d554e..0000000
--- a/src/com/google/typography/font/compression/SimpleRunner.java
+++ /dev/null
@@ -1,92 +0,0 @@
-package com.google.typography.font.compression;
-
-import com.google.common.io.Files;
-import com.google.typography.font.sfntly.Font;
-import com.google.typography.font.sfntly.FontFactory;
-import com.google.typography.font.sfntly.Tag;
-import com.google.typography.font.sfntly.table.truetype.GlyphTable;
-import com.google.typography.font.sfntly.table.truetype.LocaTable;
-
-import java.io.File;
-import java.io.IOException;
-
-/**
- * Simple WOFF 2.0 compression report runner.
- *
- * @author David Kuettel
- */
-public class SimpleRunner {
-
-  private static final FontFactory FONT_FACTORY = FontFactory.getInstance();
-
-  private static final String WOFF = "woff";
-  private static final String WOFF2 = "woff2/lzma";
-
-  private static final String TRUETYPE = "glyf/cbbox,triplet,code,reslice";
-  private static final String CFF = "";
-
-  private static final String REPORT = "report.csv";
-
-  public static void main(String[] args) throws IOException {
-    if (args.length == 0) {
-      usage();
-    }
-    CompressionStats stats = new CompressionStats();
-
-    System.out.printf("Analyzing (%d) fonts\n", args.length);
-    run(stats, args);
-
-    System.out.printf("Creating report: %s\n", REPORT);
-    CsvReport.create(stats, REPORT);
-  }
-
-  private static void run(CompressionStats stats, String[] filenames) throws IOException {
-    for (String filename : filenames) {
-      try {
-        File file = new File(filename);
-        byte[] bytes = Files.toByteArray(file);
-        Font font = FONT_FACTORY.loadFonts(bytes)[0];
-
-        byte[] woff = Experiment.run(font, WOFF);
-        byte[] woff2 = Experiment.run(font, getOptions(font));
-
-        CompressionStats.Stats stat = CompressionStats.Stats.builder()
-            .setFilename(file.getName())
-            .setSize(CompressionStats.Size.ORIGINAL, bytes.length)
-            .setSize(CompressionStats.Size.WOFF, woff.length)
-            .setSize(CompressionStats.Size.WOFF2, woff2.length)
-            .build();
-        stats.add(stat);
-
-        System.out.printf("> %s, %d, %d, %d, %.2f%%\n",
-            stat.getFilename(),
-            stat.getSize(CompressionStats.Size.ORIGINAL),
-            stat.getSize(CompressionStats.Size.WOFF),
-            stat.getSize(CompressionStats.Size.WOFF2),
-            stat.getPercent(CompressionStats.Size.WOFF, CompressionStats.Size.WOFF2));
-
-        String target = filename.replaceAll("[.](ttf|otf)", ".woff2");
-        Files.write(woff2, new File(target));
-
-      } catch (Throwable t) {
-        System.err.printf("WARNING: failed to compress: %s\n", filename);
-        t.printStackTrace();
-      }
-    }
-  }
-
-  private static boolean isTrueType(Font font) {
-    LocaTable loca = font.getTable(Tag.loca);
-    GlyphTable glyf = font.getTable(Tag.glyf);
-    return (loca != null && glyf != null);
-  }
-
-  private static String getOptions(Font font) {
-    return String.format("%s:%s", (isTrueType(font)) ? TRUETYPE : CFF, WOFF2);
-  }
-
-  private static void usage() {
-    System.err.println("Usage: SimpleRunner font...");
-    System.exit(-1);
-  }
-}
diff --git a/src/com/google/typography/font/compression/StatsCollector.java b/src/com/google/typography/font/compression/StatsCollector.java
deleted file mode 100644
index b2fead3..0000000
--- a/src/com/google/typography/font/compression/StatsCollector.java
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2011 Google Inc. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package com.google.typography.font.compression;
-
-import com.google.common.collect.Lists;
-
-import java.io.PrintWriter;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Class for gathering up stats, for summarizing and graphing.
- *
- * @author Raph Levien
- */
-public class StatsCollector {
-
-  private final List<Double> values;
-
-  public StatsCollector() {
-    values = Lists.newArrayList();
-  }
-
-  public void addStat(double value) {
-    values.add(value);
-  }
-
-  public double mean() {
-    double sum = 0;
-    for (Double value : values) {
-      sum += value;
-    }
-    return sum / values.size();
-  }
-
-  public double median() {
-    Collections.sort(values);
-    int length = values.size();
-    if (length % 2 == 1) {
-      return values.get((length - 1) / 2);
-    } else {
-      return 0.5 * (values.get(length / 2 - 1) + values.get(length / 2));
-    }
-  }
-
-  // Need to print <html> before calling this method
-  public void chartHeader(PrintWriter o, int n) {
-    o.println("<head>");
-    o.println("<script type='text/javascript' src='https://www.google.com/jsapi'></script>");
-    o.println("<script type='text/javascript'>");
-    o.println("google.load('visualization', '1', {packages:['corechart']});");
-    o.println("google.setOnLoadCallback(drawChart);");
-    o.println("function drawChart() {");
-    o.println("  var data = new google.visualization.DataTable()");
-    o.println("  data.addColumn('string', 'Font');");
-    if (n == 1) {
-      o.println("  data.addColumn('number', 'Ratio');");
-    } else {
-      for (int i = 0; i < n; i++) {
-        o.printf("  data.addColumn('number', 'Ratio %c');\n", 'A' + i);
-      }
-    }
-    o.printf("  data.addRows(%d);\n", values.size());
-  }
-
-  public void chartData(PrintWriter o, int ix) {
-    Collections.sort(values);
-    int length = values.size();
-    for (int i = 0; i < length; i++) {
-      o.printf("  data.setValue(%d, %d, %f);\n", i, ix, values.get(i));
-    }
-  }
-
-  public void chartEnd(PrintWriter o) {
-    o.println("  var chart = new google.visualization.LineChart(document.getElementById("
-        + "'chart_div'));");
-    o.println("  chart.draw(data, {width:700, height:400, title: 'Compression ratio'});");
-    o.println("}");
-    o.println("</script>");
-    o.println("</head>");
-
-    o.println();
-    o.println("<body>");
-    o.println("<div id='chart_div'></div>");
-    // TODO: split so we can get content into the HTML
-  }
-  public void chartFooter(PrintWriter o) {
-    o.println("</body>");
-    o.println("</html>");
-  }
-}
diff --git a/src/com/google/typography/font/compression/Woff2Writer.java b/src/com/google/typography/font/compression/Woff2Writer.java
deleted file mode 100644
index 905a3ce..0000000
--- a/src/com/google/typography/font/compression/Woff2Writer.java
+++ /dev/null
@@ -1,356 +0,0 @@
-// Copyright 2012 Google Inc. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package com.google.typography.font.compression;
-
-import com.google.common.collect.ImmutableBiMap;
-import com.google.common.collect.Lists;
-import com.google.typography.font.sfntly.Font;
-import com.google.typography.font.sfntly.Tag;
-import com.google.typography.font.sfntly.data.WritableFontData;
-import com.google.typography.font.sfntly.table.Table;
-import com.google.typography.font.sfntly.table.core.FontHeaderTable;
-
-import java.util.List;
-import java.util.TreeSet;
-
-/**
- * @author Raph Levien
- */
-public class Woff2Writer {
-
-  private static final long SIGNATURE = 0x774f4632;
-  private static final int WOFF2_HEADER_SIZE = 44;
-  private static final int TABLE_ENTRY_SIZE = 5 * 4;
-  private static final int FLAG_CONTINUE_STREAM = 1 << 4;
-  private static final int FLAG_APPLY_TRANSFORM = 1 << 5;
-
-  private final CompressionType compressionType;
-  private final boolean longForm;
-
-  public Woff2Writer(String args) {
-    CompressionType compressionType = CompressionType.NONE;
-    boolean longForm = false;
-    for (String arg : args.split(",")) {
-      if ("lzma".equals(arg)) {
-        compressionType = CompressionType.LZMA;
-      } else if ("gzip".equals(arg)) {
-        compressionType = CompressionType.GZIP;
-      } else if ("short".equals(arg)) {
-        longForm = false;
-      } else if ("long".equals(arg)) {
-        longForm = true;
-      }
-    }
-    this.compressionType = compressionType;
-    this.longForm = longForm;
-  }
-
-  private static ImmutableBiMap<Integer, Integer> TRANSFORM_MAP = ImmutableBiMap.of(
-      Tag.glyf, Tag.intValue(new byte[] {'g', 'l', 'z', '1'}),
-      Tag.loca, Tag.intValue(new byte[] {'l', 'o', 'c', 'z'})
-  );
-
-  public static ImmutableBiMap<Integer, Integer> getTransformMap() {
-    return TRANSFORM_MAP;
-  }
-
-  private static ImmutableBiMap<Integer, Integer> KNOWN_TABLES =
-      new ImmutableBiMap.Builder<Integer, Integer>()
-      .put(Tag.intValue(new byte[] {'c', 'm', 'a', 'p'}), 0)
-      .put(Tag.intValue(new byte[] {'h', 'e', 'a', 'd'}), 1)
-      .put(Tag.intValue(new byte[] {'h', 'h', 'e', 'a'}), 2)
-      .put(Tag.intValue(new byte[] {'h', 'm', 't', 'x'}), 3)
-      .put(Tag.intValue(new byte[] {'m', 'a', 'x', 'p'}), 4)
-      .put(Tag.intValue(new byte[] {'n', 'a', 'm', 'e'}), 5)
-      .put(Tag.intValue(new byte[] {'O', 'S', '/', '2'}), 6)
-      .put(Tag.intValue(new byte[] {'p', 'o', 's', 't'}), 7)
-      .put(Tag.intValue(new byte[] {'c', 'v', 't', ' '}), 8)
-      .put(Tag.intValue(new byte[] {'f', 'p', 'g', 'm'}), 9)
-      .put(Tag.intValue(new byte[] {'g', 'l', 'y', 'f'}), 10)
-      .put(Tag.intValue(new byte[] {'l', 'o', 'c', 'a'}), 11)
-      .put(Tag.intValue(new byte[] {'p', 'r', 'e', 'p'}), 12)
-      .put(Tag.intValue(new byte[] {'C', 'F', 'F', ' '}), 13)
-      .put(Tag.intValue(new byte[] {'V', 'O', 'R', 'G'}), 14)
-      .put(Tag.intValue(new byte[] {'E', 'B', 'D', 'T'}), 15)
-      .put(Tag.intValue(new byte[] {'E', 'B', 'L', 'C'}), 16)
-      .put(Tag.intValue(new byte[] {'g', 'a', 's', 'p'}), 17)
-      .put(Tag.intValue(new byte[] {'h', 'd', 'm', 'x'}), 18)
-      .put(Tag.intValue(new byte[] {'k', 'e', 'r', 'n'}), 19)
-      .put(Tag.intValue(new byte[] {'L', 'T', 'S', 'H'}), 20)
-      .put(Tag.intValue(new byte[] {'P', 'C', 'L', 'T'}), 21)
-      .put(Tag.intValue(new byte[] {'V', 'D', 'M', 'X'}), 22)
-      .put(Tag.intValue(new byte[] {'v', 'h', 'e', 'a'}), 23)
-      .put(Tag.intValue(new byte[] {'v', 'm', 't', 'x'}), 24)
-      .put(Tag.intValue(new byte[] {'B', 'A', 'S', 'E'}), 25)
-      .put(Tag.intValue(new byte[] {'G', 'D', 'E', 'F'}), 26)
-      .put(Tag.intValue(new byte[] {'G', 'P', 'O', 'S'}), 27)
-      .put(Tag.intValue(new byte[] {'G', 'S', 'U', 'B'}), 28)
-      .build();
-
-  public WritableFontData convert(Font font) {
-    List<TableDirectoryEntry> entries = createTableDirectoryEntries(font);
-    int size = computeCompressedFontSize(entries);
-    WritableFontData writableFontData = WritableFontData.createWritableFontData(size);
-    int index = 0;
-    FontHeaderTable head = font.getTable(Tag.head);
-    index += writeWoff2Header(writableFontData, entries, font.sfntVersion(), size,
-        head.fontRevision());
-//    System.out.printf("Wrote header, index = %d\n", index);
-    index += writeDirectory(writableFontData, index, entries);
-//    System.out.printf("Wrote directory, index = %d\n", index);
-    index += writeTables(writableFontData, index, entries);
-//    System.out.printf("Wrote tables, index = %d\n", index);
-    return writableFontData;
-  }
-
-  private List<TableDirectoryEntry> createTableDirectoryEntries(Font font) {
-    List<TableDirectoryEntry> entries = Lists.newArrayList();
-    TreeSet<Integer> tags = new TreeSet<Integer>(font.tableMap().keySet());
-
-    for (int tag : tags) {
-      Table table = font.getTable(tag);
-      byte[] uncompressedBytes = bytesFromTable(table);
-      byte[] transformedBytes = null;
-      if (TRANSFORM_MAP.containsValue(tag)) {
-        // Don't store the intermediate transformed tables under the nonstandard tags.
-        continue;
-      }
-      if (TRANSFORM_MAP.containsKey(tag)) {
-        int transformedTag = TRANSFORM_MAP.get(tag);
-        Table transformedTable = font.getTable(transformedTag);
-        if (transformedTable != null) {
-          transformedBytes = bytesFromTable(transformedTable);
-        }
-      }
-      if (transformedBytes == null) {
-        entries.add(new TableDirectoryEntry(tag, uncompressedBytes, compressionType));
-      } else {
-        entries.add(new TableDirectoryEntry(tag, uncompressedBytes, transformedBytes,
-            FLAG_APPLY_TRANSFORM, compressionType));
-      }
-    }
-    return entries;
-  }
-
-  private byte[] bytesFromTable(Table table) {
-    int length = table.dataLength();
-    byte[] bytes = new byte[length];
-    table.readFontData().readBytes(0, bytes, 0, length);
-    return bytes;
-  }
-
-  private int writeWoff2Header(WritableFontData writableFontData,
-      List<TableDirectoryEntry> entries,
-      int flavor,
-      int length,
-      int version) {
-    int index = 0;
-    index += writableFontData.writeULong(index, SIGNATURE);
-    index += writableFontData.writeULong(index, flavor);
-    index += writableFontData.writeULong(index, length);
-    index += writableFontData.writeUShort(index, entries.size());  // numTables
-    index += writableFontData.writeUShort(index, 0);  // reserved
-    int uncompressedFontSize = computeUncompressedSize(entries);
-    index += writableFontData.writeULong(index, uncompressedFontSize);
-    index += writableFontData.writeFixed(index, version);
-    index += writableFontData.writeULong(index, 0);  // metaOffset
-    index += writableFontData.writeULong(index, 0);  // metaLength
-    index += writableFontData.writeULong(index, 0);  // metaOrigLength
-    index += writableFontData.writeULong(index, 0);  // privOffset
-    index += writableFontData.writeULong(index, 0);  // privLength
-    return index;
-  }
-
-  private int writeDirectory(WritableFontData writableFontData, int offset,
-      List<TableDirectoryEntry> entries) {
-    int directorySize = computeDirectoryLength(entries);
-    for (TableDirectoryEntry entry : entries) {
-      offset += entry.writeEntry(writableFontData, offset);
-    }
-    return directorySize;
-  }
-
-  private int writeTables(WritableFontData writableFontData, int offset,
-      List<TableDirectoryEntry> entries) {
-    int start = offset;
-    for (TableDirectoryEntry entry : entries) {
-      offset += entry.writeData(writableFontData, offset);
-      offset = align4(offset);
-    }
-    return offset - start;
-  }
-
-  private int computeDirectoryLength(List<TableDirectoryEntry> entries) {
-    if (longForm) {
-      return TABLE_ENTRY_SIZE * entries.size();
-    } else {
-      int size = 0;
-      for (TableDirectoryEntry entry : entries) {
-        size += entry.writeEntry(null, size);
-      }
-      return size;
-    }
-  }
-
-  private int align4(int value) {
-    return (value + 3) & -4;
-  }
-
-  private int computeUncompressedSize(List<TableDirectoryEntry> entries) {
-    int size = 20 + 16 * entries.size();  // sfnt header length
-    for (TableDirectoryEntry entry : entries) {
-      size += entry.getOrigLength();
-      size = align4(size);
-    }
-    return size;
-  }
-
-  private int computeCompressedFontSize(List<TableDirectoryEntry> entries) {
-    int fontSize = WOFF2_HEADER_SIZE;
-    fontSize += computeDirectoryLength(entries);
-    for (TableDirectoryEntry entry : entries) {
-      fontSize += entry.getCompLength();
-      fontSize = align4(fontSize);
-    }
-    return fontSize;
-  }
-
-  private enum CompressionType {
-    NONE, GZIP, LZMA
-  }
-
-  private static long flagsForCompression(CompressionType compressionType) {
-    switch (compressionType) {
-      case NONE:
-        return 0;
-      case GZIP:
-        return 1;
-      case LZMA:
-        return 2;
-    }
-    return 0;
-  }
-
-  private static byte[] compress(byte[] input, CompressionType compressionType) {
-    switch (compressionType) {
-      case NONE:
-        return input;
-      case GZIP:
-        return GzipUtil.deflate(input);
-      case LZMA:
-        return CompressLzma.compress(input);
-    }
-    return null;
-  }
-
-  // Note: if writableFontData is null, just return the size
-  private static int writeBase128(WritableFontData writableFontData, long value, int offset) {
-    int size = 1;
-    long tmpValue = value;
-    while (tmpValue >= 128) {
-      size += 1;
-      tmpValue = tmpValue >> 7;
-    }
-    for (int i = 0; i < size; i++) {
-      int b = (int)(value >> (7 * (size - i - 1))) & 0x7f;
-      if (i < size - 1) {
-        b |= 0x80;
-      }
-      if (writableFontData != null) {
-        writableFontData.writeByte(offset, (byte)b);
-      }
-      offset += 1;
-    }
-    return size;
-  }
-
-  private class TableDirectoryEntry {
-    private final long tag;
-    private final long flags;
-    private final long origLength;
-    private final long transformLength;
-    private final byte[] bytes;
-
-    // This is the constructor for tables that don't have transforms
-    public TableDirectoryEntry(long tag, byte[] uncompressedBytes,
-        CompressionType compressionType) {
-      this(tag, uncompressedBytes, uncompressedBytes, 0, compressionType);
-    }
-
-    public TableDirectoryEntry(long tag, byte[] uncompressedBytes, byte[] transformedBytes,
-        long transformFlags, CompressionType compressionType) {
-      byte[] compressedBytes = compress(transformedBytes, compressionType);
-      if (compressedBytes.length >= transformedBytes.length) {
-        compressedBytes = transformedBytes;
-        compressionType = CompressionType.NONE;
-      }
-      this.tag = tag;
-      this.flags = transformFlags | flagsForCompression(compressionType);
-      this.origLength = uncompressedBytes.length;
-      this.transformLength = transformedBytes.length;
-      this.bytes = compressedBytes;
-    }
-
-    public long getOrigLength() {
-      return origLength;
-    }
-
-    public long getCompLength() {
-      return bytes.length;
-    }
-
-    // Note: if writableFontData is null, just return the size
-    public int writeEntry(WritableFontData writableFontData, int offset) {
-      if (longForm) {
-        if (writableFontData != null) {
-          offset += writableFontData.writeULong(offset, tag);
-          offset += writableFontData.writeULong(offset, flags);
-          offset += writableFontData.writeULong(offset, getCompLength());
-          offset += writableFontData.writeULong(offset, transformLength);
-          offset += writableFontData.writeULong(offset, getOrigLength());
-        }
-        return TABLE_ENTRY_SIZE;
-      } else {
-        int start = offset;
-        int flag_byte = 0x1f;
-        if (KNOWN_TABLES.containsKey((int)tag)) {
-          flag_byte = KNOWN_TABLES.get((int)tag);
-        }
-        if ((flags & FLAG_APPLY_TRANSFORM) != 0) {
-          flag_byte |= 0x20;
-        }
-        if ((flags & FLAG_CONTINUE_STREAM) != 0) {
-          flag_byte |= 0xc0;
-        } else {
-          flag_byte |= (flags & 3) << 6;
-        }
-        if (writableFontData != null) {
-//          System.out.printf("%d: tag = %08x, flag = %02x\n", offset, tag, flag_byte);
-          writableFontData.writeByte(offset, (byte)flag_byte);
-        }
-        offset += 1;
-        if ((flag_byte & 0x1f) == 0x1f) {
-          if (writableFontData != null) {
-            writableFontData.writeULong(offset, tag);
-          }
-          offset += 4;
-        }
-        offset += writeBase128(writableFontData, getOrigLength(), offset);
-        if ((flag_byte & 0x20) != 0) {
-          offset += writeBase128(writableFontData, transformLength, offset);
-        }
-        if ((flag_byte & 0xc0) == 0x40 || (flag_byte & 0xc0) == 0x80) {
-          offset += writeBase128(writableFontData, getCompLength(), offset);
-        }
-        return offset - start;
-      }
-    }
-
-    public int writeData(WritableFontData writableFontData, int offset) {
-      writableFontData.writeBytes(offset, bytes);
-      return bytes.length;
-    }
-  }
-}
