diff --git a/Lib/fontTools/merge.py b/Lib/fontTools/merge.py
new file mode 100644
index 0000000..b576b59
--- /dev/null
+++ b/Lib/fontTools/merge.py
@@ -0,0 +1,457 @@
+# Copyright 2013 Google, Inc. All Rights Reserved.
+#
+# Google Author(s): Behdad Esfahbod
+
+"""Font merger.
+"""
+
+import sys
+import time
+
+import fontTools
+from fontTools import misc, ttLib, cffLib
+from fontTools.ttLib.tables import otTables
+
+def _add_method(*clazzes):
+	"""Returns a decorator function that adds a new method to one or
+	more classes."""
+	def wrapper(method):
+		for clazz in clazzes:
+			assert clazz.__name__ != 'DefaultTable', 'Oops, table class not found.'
+			assert not hasattr(clazz, method.func_name), \
+				"Oops, class '%s' has method '%s'." % (clazz.__name__,
+								       method.func_name)
+		setattr(clazz, method.func_name, method)
+		return None
+	return wrapper
+
+
+@_add_method(ttLib.getTableClass('maxp'))
+def merge(self, m):
+	# TODO When we correctly merge hinting data, update these values:
+	# maxFunctionDefs, maxInstructionDefs, maxSizeOfInstructions
+	# TODO Assumes that all tables have format 1.0; safe assumption.
+	allKeys = reduce(set.union, (vars(table).keys() for table in m.tables), set())
+	for key in allKeys:
+		setattr(self, key, max(getattr(table, key) for table in m.tables))
+	return True
+
+@_add_method(ttLib.getTableClass('head'))
+def merge(self, m):
+	# TODO Check that unitsPerEm are the same.
+	# TODO Use bitwise ops for flags, macStyle, fontDirectionHint
+	minMembers = ['xMin', 'yMin']
+	# Negate some members
+	for key in minMembers:
+		for table in m.tables:
+			setattr(table, key, -getattr(table, key))
+	# Get max over members
+	allKeys = reduce(set.union, (vars(table).keys() for table in m.tables), set())
+	for key in allKeys:
+		setattr(self, key, max(getattr(table, key) for table in m.tables))
+	# Negate them back
+	for key in minMembers:
+		for table in m.tables:
+			setattr(table, key, -getattr(table, key))
+		setattr(self, key, -getattr(self, key))
+	return True
+
+@_add_method(ttLib.getTableClass('hhea'))
+def merge(self, m):
+	# TODO Check that ascent, descent, slope, etc are the same.
+	minMembers = ['descent', 'minLeftSideBearing', 'minRightSideBearing']
+	# Negate some members
+	for key in minMembers:
+		for table in m.tables:
+			setattr(table, key, -getattr(table, key))
+	# Get max over members
+	allKeys = reduce(set.union, (vars(table).keys() for table in m.tables), set())
+	for key in allKeys:
+		setattr(self, key, max(getattr(table, key) for table in m.tables))
+	# Negate them back
+	for key in minMembers:
+		for table in m.tables:
+			setattr(table, key, -getattr(table, key))
+		setattr(self, key, -getattr(self, key))
+	return True
+
+@_add_method(ttLib.getTableClass('OS/2'))
+def merge(self, m):
+	# TODO Check that weight/width/subscript/superscript/etc are the same.
+	# TODO Bitwise ops for UnicodeRange/CodePageRange.
+	# TODO Pretty much all fields generated here have bogus values.
+	# Get max over members
+	allKeys = reduce(set.union, (vars(table).keys() for table in m.tables), set())
+	for key in allKeys:
+		setattr(self, key, max(getattr(table, key) for table in m.tables))
+	return True
+
+@_add_method(ttLib.getTableClass('post'))
+def merge(self, m):
+	# TODO Check that italicAngle, underlinePosition, underlineThickness are the same.
+	minMembers = ['underlinePosition', 'minMemType42', 'minMemType1']
+	# Negate some members
+	for key in minMembers:
+		for table in m.tables:
+			setattr(table, key, -getattr(table, key))
+	# Get max over members
+	allKeys = reduce(set.union, (vars(table).keys() for table in m.tables), set())
+	if 'mapping' in allKeys:
+		allKeys.remove('mapping')
+	allKeys.remove('extraNames')
+	for key in allKeys:
+		setattr(self, key, max(getattr(table, key) for table in m.tables))
+	# Negate them back
+	for key in minMembers:
+		for table in m.tables:
+			setattr(table, key, -getattr(table, key))
+		setattr(self, key, -getattr(self, key))
+	self.mapping = {}
+	for table in m.tables:
+		if hasattr(table, 'mapping'):
+			self.mapping.update(table.mapping)
+	self.extraNames = []
+	return True
+
+@_add_method(ttLib.getTableClass('vmtx'),
+             ttLib.getTableClass('hmtx'))
+def merge(self, m):
+	self.metrics = {}
+	for table in m.tables:
+		self.metrics.update(table.metrics)
+	return True
+
+@_add_method(ttLib.getTableClass('loca'))
+def merge(self, m):
+	return True # Will be computed automatically
+
+@_add_method(ttLib.getTableClass('glyf'))
+def merge(self, m):
+	self.glyphs = {}
+	for table in m.tables:
+		for g in table.glyphs.values():
+			# Drop hints for now, since we don't remap
+			# functions / CVT values.
+			g.removeHinting()
+			# Expand composite glyphs to load their
+			# composite glyph names.
+			if g.isComposite():
+				g.expand(table)
+		self.glyphs.update(table.glyphs)
+	return True
+
+@_add_method(ttLib.getTableClass('prep'),
+	     ttLib.getTableClass('fpgm'),
+	     ttLib.getTableClass('cvt '))
+def merge(self, m):
+	return False # TODO We don't merge hinting data currently.
+
+@_add_method(ttLib.getTableClass('cmap'))
+def merge(self, m):
+	# TODO Handle format=14.
+	cmapTables = [t for table in m.tables for t in table.tables
+		      if t.platformID == 3 and t.platEncID in [1, 10]]
+	# TODO Better handle format-4 and format-12 coexisting in same font.
+	# TODO Insert both a format-4 and format-12 if needed.
+	module = ttLib.getTableModule('cmap')
+	assert all(t.format in [4, 12] for t in cmapTables)
+	format = max(t.format for t in cmapTables)
+	cmapTable = module.cmap_classes[format](format)
+	cmapTable.cmap = {}
+	cmapTable.platformID = 3
+	cmapTable.platEncID = max(t.platEncID for t in cmapTables)
+	cmapTable.language = 0
+	for table in cmapTables:
+		# TODO handle duplicates.
+		cmapTable.cmap.update(table.cmap)
+	self.tableVersion = 0
+	self.tables = [cmapTable]
+	self.numSubTables = len(self.tables)
+	return True
+
+@_add_method(ttLib.getTableClass('GDEF'))
+def merge(self, m):
+	self.table = otTables.GDEF()
+	self.table.Version = 1.0 # TODO version 1.2...
+
+	if any(t.table.LigCaretList for t in m.tables):
+		glyphs = []
+		ligGlyphs = []
+		for table in m.tables:
+			if table.table.LigCaretList:
+				glyphs.extend(table.table.LigCaretList.Coverage.glyphs)
+				ligGlyphs.extend(table.table.LigCaretList.LigGlyph)
+		coverage = otTables.Coverage()
+		coverage.glyphs = glyphs
+		ligCaretList = otTables.LigCaretList()
+		ligCaretList.Coverage = coverage
+		ligCaretList.LigGlyph = ligGlyphs
+		ligCaretList.GlyphCount = len(ligGlyphs)
+		self.table.LigCaretList = ligCaretList
+	else:
+		self.table.LigCaretList = None
+
+	if any(t.table.MarkAttachClassDef for t in m.tables):
+		classDefs = {}
+		for table in m.tables:
+			if table.table.MarkAttachClassDef:
+				classDefs.update(table.table.MarkAttachClassDef.classDefs)
+		self.table.MarkAttachClassDef = otTables.MarkAttachClassDef()
+		self.table.MarkAttachClassDef.classDefs = classDefs
+	else:
+		self.table.MarkAttachClassDef = None
+
+	if any(t.table.GlyphClassDef for t in m.tables):
+		classDefs = {}
+		for table in m.tables:
+			if table.table.GlyphClassDef:
+				classDefs.update(table.table.GlyphClassDef.classDefs)
+		self.table.GlyphClassDef = otTables.GlyphClassDef()
+		self.table.GlyphClassDef.classDefs = classDefs
+	else:
+		self.table.GlyphClassDef = None
+
+	if any(t.table.AttachList for t in m.tables):
+		glyphs = []
+		attachPoints = []
+		for table in m.tables:
+			if table.table.AttachList:
+				glyphs.extend(table.table.AttachList.Coverage.glyphs)
+				attachPoints.extend(table.table.AttachList.AttachPoint)
+		coverage = otTables.Coverage()
+		coverage.glyphs = glyphs
+		attachList = otTables.AttachList()
+		attachList.Coverage = coverage
+		attachList.AttachPoint = attachPoints
+		attachList.GlyphCount = len(attachPoints)
+		self.table.AttachList = attachList
+	else:
+		self.table.AttachList = None
+
+	return True
+
+
+class Options(object):
+
+  class UnknownOptionError(Exception):
+    pass
+
+  _drop_tables_default = ['fpgm', 'prep', 'cvt ', 'gasp']
+  drop_tables = _drop_tables_default
+
+  def __init__(self, **kwargs):
+
+    self.set(**kwargs)
+
+  def set(self, **kwargs):
+    for k,v in kwargs.iteritems():
+      if not hasattr(self, k):
+        raise self.UnknownOptionError("Unknown option '%s'" % k)
+      setattr(self, k, v)
+
+  def parse_opts(self, argv, ignore_unknown=False):
+    ret = []
+    opts = {}
+    for a in argv:
+      orig_a = a
+      if not a.startswith('--'):
+        ret.append(a)
+        continue
+      a = a[2:]
+      i = a.find('=')
+      op = '='
+      if i == -1:
+        if a.startswith("no-"):
+          k = a[3:]
+          v = False
+        else:
+          k = a
+          v = True
+      else:
+        k = a[:i]
+        if k[-1] in "-+":
+          op = k[-1]+'='  # Ops is '-=' or '+=' now.
+          k = k[:-1]
+        v = a[i+1:]
+      k = k.replace('-', '_')
+      if not hasattr(self, k):
+        if ignore_unknown == True or k in ignore_unknown:
+          ret.append(orig_a)
+          continue
+        else:
+          raise self.UnknownOptionError("Unknown option '%s'" % a)
+
+      ov = getattr(self, k)
+      if isinstance(ov, bool):
+        v = bool(v)
+      elif isinstance(ov, int):
+        v = int(v)
+      elif isinstance(ov, list):
+        vv = v.split(',')
+        if vv == ['']:
+          vv = []
+        vv = [int(x, 0) if len(x) and x[0] in "0123456789" else x for x in vv]
+        if op == '=':
+          v = vv
+        elif op == '+=':
+          v = ov
+          v.extend(vv)
+        elif op == '-=':
+          v = ov
+          for x in vv:
+            if x in v:
+              v.remove(x)
+        else:
+          assert 0
+
+      opts[k] = v
+    self.set(**opts)
+
+    return ret
+
+
+class Merger:
+
+	def __init__(self, options=None, log=None):
+
+		if not log:
+			log = Logger()
+		if not options:
+			options = Options()
+
+		self.options = options
+		self.log = log
+
+	def merge(self, fontfiles):
+
+		mega = ttLib.TTFont()
+
+		#
+		# Settle on a mega glyph order.
+		#
+		fonts = [ttLib.TTFont(fontfile) for fontfile in fontfiles]
+		glyphOrders = [font.getGlyphOrder() for font in fonts]
+		megaGlyphOrder = self._mergeGlyphOrders(glyphOrders)
+		# Reload fonts and set new glyph names on them.
+		# TODO Is it necessary to reload font?  I think it is.  At least
+		# it's safer, in case tables were loaded to provide glyph names.
+		fonts = [ttLib.TTFont(fontfile) for fontfile in fontfiles]
+		for font,glyphOrder in zip(fonts, glyphOrders):
+			font.setGlyphOrder(glyphOrder)
+		mega.setGlyphOrder(megaGlyphOrder)
+
+		allTags = reduce(set.union, (font.keys() for font in fonts), set())
+		allTags.remove('GlyphOrder')
+		for tag in allTags:
+
+			if tag in self.options.drop_tables:
+				self.log("Dropping '%s'." % tag)
+				continue
+
+			clazz = ttLib.getTableClass(tag)
+
+			if not hasattr(clazz, 'merge'):
+				self.log("Don't know how to merge '%s', dropped." % tag)
+				continue
+
+			# TODO For now assume all fonts have the same tables.
+			self.tables = [font[tag] for font in fonts]
+			table = clazz(tag)
+			if table.merge (self):
+				mega[tag] = table
+				self.log("Merged '%s'." % tag)
+			else:
+				self.log("Dropped '%s'.  No need to merge explicitly." % tag)
+			self.log.lapse("merge '%s'" % tag)
+			del self.tables
+
+		return mega
+
+	def _mergeGlyphOrders(self, glyphOrders):
+		"""Modifies passed-in glyphOrders to reflect new glyph names.
+		Returns glyphOrder for the merged font."""
+		# Simply append font index to the glyph name for now.
+		# TODO Even this simplistic numbering can result in conflicts.
+		# But then again, we have to improve this soon anyway.
+		mega = []
+		for n,glyphOrder in enumerate(glyphOrders):
+			for i,glyphName in enumerate(glyphOrder):
+				glyphName += "#" + `n`
+				glyphOrder[i] = glyphName
+				mega.append(glyphName)
+		return mega
+
+
+class Logger(object):
+
+  def __init__(self, verbose=False, xml=False, timing=False):
+    self.verbose = verbose
+    self.xml = xml
+    self.timing = timing
+    self.last_time = self.start_time = time.time()
+
+  def parse_opts(self, argv):
+    argv = argv[:]
+    for v in ['verbose', 'xml', 'timing']:
+      if "--"+v in argv:
+        setattr(self, v, True)
+        argv.remove("--"+v)
+    return argv
+
+  def __call__(self, *things):
+    if not self.verbose:
+      return
+    print ' '.join(str(x) for x in things)
+
+  def lapse(self, *things):
+    if not self.timing:
+      return
+    new_time = time.time()
+    print "Took %0.3fs to %s" %(new_time - self.last_time,
+                                 ' '.join(str(x) for x in things))
+    self.last_time = new_time
+
+  def font(self, font, file=sys.stdout):
+    if not self.xml:
+      return
+    from fontTools.misc import xmlWriter
+    writer = xmlWriter.XMLWriter(file)
+    font.disassembleInstructions = False  # Work around ttLib bug
+    for tag in font.keys():
+      writer.begintag(tag)
+      writer.newline()
+      font[tag].toXML(writer, font)
+      writer.endtag(tag)
+      writer.newline()
+
+
+__all__ = [
+  'Options',
+  'Merger',
+  'Logger',
+  'main'
+]
+
+def main(args):
+
+	log = Logger()
+	args = log.parse_opts(args)
+
+	options = Options()
+	args = options.parse_opts(args)
+
+	if len(args) < 1:
+		print >>sys.stderr, "usage: pyftmerge font..."
+		sys.exit(1)
+
+	merger = Merger(options=options, log=log)
+	font = merger.merge(args)
+	outfile = 'merged.ttf'
+	font.save(outfile)
+	log.lapse("compile and save font")
+
+	log.last_time = log.start_time
+	log.lapse("make one with everything(TOTAL TIME)")
+
+if __name__ == "__main__":
+	main(sys.argv[1:])
diff --git a/Lib/fontTools/subset.py b/Lib/fontTools/subset.py
index a3b9f70..8ce37f2 100644
--- a/Lib/fontTools/subset.py
+++ b/Lib/fontTools/subset.py
@@ -2161,8 +2161,8 @@
               for g in args))
 
   font = load_font(fontfile, options, dontLoadGlyphNames=dontLoadGlyphNames)
-  subsetter = Subsetter(options=options, log=log)
   log.lapse("load font")
+  subsetter = Subsetter(options=options, log=log)
 
   names = font.getGlyphNames()
   log.lapse("loading glyph names")
diff --git a/Tools/pyftmerge b/Tools/pyftmerge
new file mode 100755
index 0000000..2479258
--- /dev/null
+++ b/Tools/pyftmerge
@@ -0,0 +1,6 @@
+#! /usr/bin/env python
+
+import sys
+from fontTools import merge
+
+merge.main(sys.argv[1:])
