diff --git a/import_ext.py b/import_ext.py
deleted file mode 100644
index 2a1ebf8..0000000
--- a/import_ext.py
+++ /dev/null
@@ -1,422 +0,0 @@
-#
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import os
-import random
-import stat
-import sys
-import urllib2
-import StringIO
-
-from error import GitError, ImportError
-from git_command import GitCommand
-
-class ImportExternal(object):
-  """Imports a single revision from a non-git data source.
-     Suitable for use to import a tar or zip based snapshot.
-  """
-  def __init__(self):
-    self._marks = 0
-    self._files = {}
-    self._tempref = 'refs/repo-external/import'
-
-    self._urls = []
-    self._remap = []
-    self.parent = None
-    self._user_name = 'Upstream'
-    self._user_email = 'upstream-import@none'
-    self._user_when = 1000000
-
-    self.commit = None
-
-  def Clone(self):
-    r = self.__class__()
-
-    r.project = self.project
-    for u in self._urls:
-      r._urls.append(u)
-    for p in self._remap:
-      r._remap.append(_PathMap(r, p._old, p._new))
-
-    return r
-
-  def SetProject(self, project):
-    self.project = project
-
-  def SetVersion(self, version):
-    self.version = version
-
-  def AddUrl(self, url):
-    self._urls.append(url)
-
-  def SetParent(self, commit_hash):
-    self.parent = commit_hash
-
-  def SetCommit(self, commit_hash):
-    self.commit = commit_hash
-
-  def RemapPath(self, old, new, replace_version=True):
-    self._remap.append(_PathMap(self, old, new))
-
-  @property
-  def TagName(self):
-    v = ''
-    for c in self.version:
-      if c >= '0' and c <= '9':
-        v += c
-      elif c >= 'A' and c <= 'Z':
-        v += c
-      elif c >= 'a' and c <= 'z':
-        v += c
-      elif c in ('-', '_', '.', '/', '+', '@'):
-        v += c
-    return 'upstream/%s' % v
-
-  @property
-  def PackageName(self):
-    n = self.project.name
-    if n.startswith('platform/'):
-      # This was not my finest moment...
-      #
-      n = n[len('platform/'):]
-    return n
-
-  def Import(self):
-    self._need_graft = False
-    if self.parent:
-      try:
-        self.project.bare_git.cat_file('-e', self.parent)
-      except GitError:
-        self._need_graft = True
-
-    gfi = GitCommand(self.project,
-                     ['fast-import', '--force', '--quiet'],
-                     bare = True,
-                     provide_stdin = True)
-    try:
-      self._out = gfi.stdin
-
-      try:
-        self._UnpackFiles()
-        self._MakeCommit()
-        self._out.flush()
-      finally:
-        rc = gfi.Wait()
-      if rc != 0:
-        raise ImportError('fast-import failed')
-
-      if self._need_graft:
-        id = self._GraftCommit()
-      else:
-        id = self.project.bare_git.rev_parse('%s^0' % self._tempref)
-
-      if self.commit and self.commit != id:
-        raise ImportError('checksum mismatch: %s expected,'
-                          ' %s imported' % (self.commit, id))
-
-      self._MakeTag(id)
-      return id
-    finally:
-      try:
-        self.project.bare_git.DeleteRef(self._tempref)
-      except GitError:
-        pass
-
-  def _PickUrl(self, failed):
-    u = map(lambda x: x.replace('%version%', self.version), self._urls)
-    for f in failed:
-      if f in u:
-        u.remove(f)
-    if len(u) == 0:
-      return None
-    return random.choice(u)
-
-  def _OpenUrl(self):
-    failed = {}
-    while True:
-      url = self._PickUrl(failed.keys())
-      if url is None:
-        why = 'Cannot download %s' % self.project.name
-
-        if failed:
-          why += ': one or more mirrors are down\n'
-          bad_urls = list(failed.keys())
-          bad_urls.sort()
-          for url in bad_urls:
-            why += '  %s: %s\n' % (url, failed[url])
-        else:
-          why += ': no mirror URLs'
-        raise ImportError(why)
-
-      print >>sys.stderr, "Getting %s ..." % url
-      try:
-        return urllib2.urlopen(url), url
-      except urllib2.HTTPError, e:
-        failed[url] = e.code
-      except urllib2.URLError, e:
-        failed[url] = e.reason[1]
-      except OSError, e:
-        failed[url] = e.strerror
-
-  def _UnpackFiles(self):
-    raise NotImplementedError
-
-  def _NextMark(self):
-    self._marks += 1
-    return self._marks
-
-  def _UnpackOneFile(self, mode, size, name, fd):
-    if stat.S_ISDIR(mode):    # directory
-      return
-    else:
-      mode = self._CleanMode(mode, name)
-
-    old_name = name
-    name = self._CleanName(name)
-
-    if stat.S_ISLNK(mode) and self._remap:
-      # The link is relative to the old_name, and may need to
-      # be rewritten according to our remap rules if it goes
-      # up high enough in the tree structure.
-      #
-      dest = self._RewriteLink(fd.read(size), old_name, name)
-      fd = StringIO.StringIO(dest)
-      size = len(dest)
-
-    fi = _File(mode, name, self._NextMark())
-
-    self._out.write('blob\n')
-    self._out.write('mark :%d\n' % fi.mark)
-    self._out.write('data %d\n' % size)
-    while size > 0:
-      n = min(2048, size)
-      self._out.write(fd.read(n))
-      size -= n
-    self._out.write('\n')
-    self._files[fi.name] = fi
-
-  def _SetFileMode(self, name, mode):
-    if not stat.S_ISDIR(mode):
-      mode = self._CleanMode(mode, name)
-      name = self._CleanName(name)
-      try:
-        fi = self._files[name]
-      except KeyError:
-        raise ImportError('file %s was not unpacked' % name)
-      fi.mode = mode
-
-  def _RewriteLink(self, dest, relto_old, relto_new):
-    # Drop the last components of the symlink itself
-    # as the dest is relative to the directory its in.
-    #
-    relto_old = _TrimPath(relto_old)
-    relto_new = _TrimPath(relto_new)
-
-    # Resolve the link to be absolute from the top of
-    # the archive, so we can remap its destination.
-    #
-    while dest.find('/./') >= 0 or dest.find('//') >= 0:
-      dest = dest.replace('/./', '/')
-      dest = dest.replace('//', '/')
-
-    if dest.startswith('../') or dest.find('/../') > 0:
-      dest = _FoldPath('%s/%s' % (relto_old, dest))
-
-    for pm in self._remap:
-      if pm.Matches(dest):
-        dest = pm.Apply(dest)
-        break
-
-    dest, relto_new = _StripCommonPrefix(dest, relto_new)
-    while relto_new:
-      i = relto_new.find('/')
-      if i > 0:
-        relto_new = relto_new[i + 1:]
-      else:
-        relto_new = ''
-      dest = '../' + dest
-    return dest
-
-  def _CleanMode(self, mode, name):
-    if stat.S_ISREG(mode):  # regular file
-      if (mode & 0111) == 0:
-        return 0644
-      else:
-        return 0755
-    elif stat.S_ISLNK(mode):  # symlink
-      return stat.S_IFLNK
-    else:
-      raise ImportError('invalid mode %o in %s' % (mode, name))
-
-  def _CleanName(self, name):
-    old_name = name
-    for pm in self._remap:
-      if pm.Matches(name):
-        name = pm.Apply(name)
-        break
-    while name.startswith('/'):
-      name = name[1:]
-    if not name:
-      raise ImportError('path %s is empty after remap' % old_name)
-    if name.find('/./') >= 0 or name.find('/../') >= 0:
-      raise ImportError('path %s contains relative parts' % name)
-    return name
-
-  def _MakeCommit(self):
-    msg = '%s %s\n' % (self.PackageName, self.version)
-
-    self._out.write('commit %s\n' % self._tempref)
-    self._out.write('committer %s <%s> %d +0000\n' % (
-                    self._user_name,
-                    self._user_email,
-                    self._user_when))
-    self._out.write('data %d\n' % len(msg))
-    self._out.write(msg)
-    self._out.write('\n')
-    if self.parent and not self._need_graft:
-      self._out.write('from %s^0\n' % self.parent)
-      self._out.write('deleteall\n')
-
-    for f in self._files.values():
-      self._out.write('M %o :%d %s\n' % (f.mode, f.mark, f.name))
-    self._out.write('\n')
-
-  def _GraftCommit(self):
-    raw = self.project.bare_git.cat_file('commit', self._tempref)
-    raw = raw.split("\n")
-    while raw[1].startswith('parent '):
-      del raw[1]
-    raw.insert(1, 'parent %s' % self.parent)
-    id = self._WriteObject('commit', "\n".join(raw))
-
-    graft_file = os.path.join(self.project.gitdir, 'info/grafts')
-    if os.path.exists(graft_file):
-      graft_list = open(graft_file, 'rb').read().split("\n")
-      if graft_list and graft_list[-1] == '':
-        del graft_list[-1]
-    else:
-      graft_list = []
-
-    exists = False
-    for line in graft_list:
-      if line == id:
-        exists = True
-        break
-
-    if not exists:
-      graft_list.append(id)
-      graft_list.append('')
-      fd = open(graft_file, 'wb')
-      fd.write("\n".join(graft_list))
-      fd.close()
-
-    return id
-
-  def _MakeTag(self, id):
-    name = self.TagName
-
-    raw = []
-    raw.append('object %s' % id)
-    raw.append('type commit')
-    raw.append('tag %s' % name)
-    raw.append('tagger %s <%s> %d +0000' % (
-      self._user_name,
-      self._user_email,
-      self._user_when))
-    raw.append('')
-    raw.append('%s %s\n' % (self.PackageName, self.version))
-
-    tagid = self._WriteObject('tag', "\n".join(raw))
-    self.project.bare_git.UpdateRef('refs/tags/%s' % name, tagid)
-
-  def _WriteObject(self, type, data):
-    wo = GitCommand(self.project,
-                    ['hash-object', '-t', type, '-w', '--stdin'],
-                    bare = True,
-                    provide_stdin = True,
-                    capture_stdout = True,
-                    capture_stderr = True)
-    wo.stdin.write(data)
-    if wo.Wait() != 0:
-      raise GitError('cannot create %s from (%s)' % (type, data))
-    return wo.stdout[:-1]
-
-
-def _TrimPath(path):
-  i = path.rfind('/')
-  if i > 0:
-    path = path[0:i]
-  return ''
-
-def _StripCommonPrefix(a, b):
-  while True:
-    ai = a.find('/')
-    bi = b.find('/')
-    if ai > 0 and bi > 0 and a[0:ai] == b[0:bi]:
-      a = a[ai + 1:]
-      b = b[bi + 1:]
-    else:
-      break
-  return a, b
-
-def _FoldPath(path):
-  while True:
-    if path.startswith('../'):
-      return path
-
-    i = path.find('/../')
-    if i <= 0:
-      if path.startswith('/'):
-        return path[1:]
-      return path
-
-    lhs = path[0:i]
-    rhs = path[i + 4:]
-
-    i = lhs.rfind('/')
-    if i > 0:
-      path = lhs[0:i + 1] + rhs
-    else:
-      path = rhs
-
-class _File(object):
-  def __init__(self, mode, name, mark):
-    self.mode = mode
-    self.name = name
-    self.mark = mark
-
-
-class _PathMap(object):
-  def __init__(self, imp, old, new):
-    self._imp = imp
-    self._old = old
-    self._new = new
-
-  def _r(self, p):
-    return p.replace('%version%', self._imp.version)
-
-  @property
-  def old(self):
-    return self._r(self._old)
-
-  @property
-  def new(self):
-    return self._r(self._new)
-
-  def Matches(self, name):
-    return name.startswith(self.old)
-
-  def Apply(self, name):
-    return self.new + name[len(self.old):]
diff --git a/import_tar.py b/import_tar.py
deleted file mode 100644
index d7ce14d..0000000
--- a/import_tar.py
+++ /dev/null
@@ -1,206 +0,0 @@
-#
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import bz2
-import stat
-import tarfile
-import zlib
-import StringIO
-
-from import_ext import ImportExternal
-from error import ImportError
-
-class ImportTar(ImportExternal):
-  """Streams a (optionally compressed) tar file from the network
-     directly into a Project's Git repository.
-  """
-  @classmethod
-  def CanAccept(cls, url):
-    """Can this importer read and unpack the data stored at url?
-    """
-    if url.endswith('.tar.gz') or url.endswith('.tgz'):
-      return True
-    if url.endswith('.tar.bz2'):
-      return True
-    if url.endswith('.tar'):
-      return True
-    return False
-
-  def _UnpackFiles(self):
-    url_fd, url = self._OpenUrl()
-    try:
-      if url.endswith('.tar.gz') or url.endswith('.tgz'):
-        tar_fd = _Gzip(url_fd)
-      elif url.endswith('.tar.bz2'):
-        tar_fd = _Bzip2(url_fd)
-      elif url.endswith('.tar'):
-        tar_fd = _Raw(url_fd)
-      else:
-        raise ImportError('non-tar file extension: %s' % url)
-
-      try:
-        tar = tarfile.TarFile(name = url,
-                              mode = 'r',
-                              fileobj = tar_fd)
-        try:
-          for entry in tar:
-            mode = entry.mode
-
-            if (mode & 0170000) == 0:
-              if entry.isdir():
-                mode |= stat.S_IFDIR
-              elif entry.isfile() or entry.islnk():  # hard links as files
-                mode |= stat.S_IFREG
-              elif entry.issym():
-                mode |= stat.S_IFLNK
-
-            if stat.S_ISLNK(mode):   # symlink
-              data_fd = StringIO.StringIO(entry.linkname)
-              data_sz = len(entry.linkname)
-            elif stat.S_ISDIR(mode): # directory
-              data_fd = StringIO.StringIO('')
-              data_sz = 0
-            else:
-              data_fd = tar.extractfile(entry)
-              data_sz = entry.size
-
-            self._UnpackOneFile(mode, data_sz, entry.name, data_fd)
-        finally:
-          tar.close()
-      finally:
-        tar_fd.close()
-    finally:
-      url_fd.close()
-
-
-
-class _DecompressStream(object):
-  """file like object to decompress a tar stream
-  """
-  def __init__(self, fd):
-    self._fd = fd
-    self._pos = 0
-    self._buf = None
-
-  def tell(self):
-    return self._pos
-
-  def seek(self, offset):
-    d = offset - self._pos
-    if d > 0:
-      self.read(d)
-    elif d == 0:
-      pass
-    else:
-      raise NotImplementedError, 'seek backwards'
-
-  def close(self):
-    self._fd = None
-
-  def read(self, size = -1):
-    if not self._fd:
-      raise EOFError, 'Reached EOF'
-    
-    r = []
-    try:
-      if size >= 0:
-        self._ReadChunk(r, size)
-      else:
-        while True:
-          self._ReadChunk(r, 2048)
-    except EOFError:
-      pass
-
-    if len(r) == 1:
-      r = r[0]
-    else:
-      r = ''.join(r)
-    self._pos += len(r)
-    return r
-
-  def _ReadChunk(self, r, size):
-    b = self._buf
-    try:
-      while size > 0:
-        if b is None or len(b) == 0:
-          b = self._Decompress(self._fd.read(2048))
-          continue
-
-        use = min(size, len(b))
-        r.append(b[:use])
-        b = b[use:]
-        size -= use
-    finally:
-      self._buf = b
-
-  def _Decompress(self, b):
-    raise NotImplementedError, '_Decompress'
-
-
-class _Raw(_DecompressStream):
-  """file like object for an uncompressed stream
-  """
-  def __init__(self, fd):
-    _DecompressStream.__init__(self, fd)
-
-  def _Decompress(self, b):
-    return b
-
-
-class _Bzip2(_DecompressStream):
-  """file like object to decompress a .bz2 stream
-  """
-  def __init__(self, fd):
-    _DecompressStream.__init__(self, fd)
-    self._bz = bz2.BZ2Decompressor()
-
-  def _Decompress(self, b):
-    return self._bz.decompress(b)
-
-
-_FHCRC, _FEXTRA, _FNAME, _FCOMMENT = 2, 4, 8, 16
-class _Gzip(_DecompressStream):
-  """file like object to decompress a .gz stream
-  """
-  def __init__(self, fd):
-    _DecompressStream.__init__(self, fd)
-    self._z = zlib.decompressobj(-zlib.MAX_WBITS)
-
-    magic = fd.read(2)
-    if magic != '\037\213':
-      raise IOError, 'Not a gzipped file'
-
-    method = ord(fd.read(1))
-    if method != 8:
-      raise IOError, 'Unknown compression method'
-
-    flag = ord(fd.read(1))
-    fd.read(6)
-
-    if flag & _FEXTRA:
-      xlen = ord(fd.read(1))
-      xlen += 256 * ord(fd.read(1))
-      fd.read(xlen)
-    if flag & _FNAME:
-      while fd.read(1) != '\0':
-        pass
-    if flag & _FCOMMENT:
-      while fd.read(1) != '\0':
-        pass
-    if flag & _FHCRC:
-      fd.read(2)
-
-  def _Decompress(self, b):
-    return self._z.decompress(b)
diff --git a/import_zip.py b/import_zip.py
deleted file mode 100644
index 08aff32..0000000
--- a/import_zip.py
+++ /dev/null
@@ -1,345 +0,0 @@
-#
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import stat
-import struct
-import zlib
-import cStringIO
-
-from import_ext import ImportExternal
-from error import ImportError
-
-class ImportZip(ImportExternal):
-  """Streams a zip file from the network directly into a Project's
-     Git repository.
-  """
-  @classmethod
-  def CanAccept(cls, url):
-    """Can this importer read and unpack the data stored at url?
-    """
-    if url.endswith('.zip') or url.endswith('.jar'):
-      return True
-    return False
-
-  def _UnpackFiles(self):
-    url_fd, url = self._OpenUrl()
-    try:
-      if not self.__class__.CanAccept(url):
-        raise ImportError('non-zip file extension: %s' % url)
-
-      zip = _ZipFile(url_fd)
-      for entry in zip.FileRecords():
-        data = zip.Open(entry).read()
-        sz = len(data)
-
-        if data and _SafeCRLF(data):
-          data = data.replace('\r\n', '\n')
-          sz = len(data)
-
-        fd = cStringIO.StringIO(data)
-        self._UnpackOneFile(entry.mode, sz, entry.name, fd)
-        zip.Close(entry)
-
-      for entry in zip.CentralDirectory():
-        self._SetFileMode(entry.name, entry.mode)
-
-      zip.CheckTail()
-    finally:
-      url_fd.close()
-
-
-def _SafeCRLF(data):
-  """Is it reasonably safe to perform a CRLF->LF conversion?
-
-     If the stream contains a NUL byte it is likely binary,
-     and thus a CRLF->LF conversion may damage the stream.
-
-     If the only NUL is in the last position of the stream,
-     but it otherwise can do a CRLF<->LF conversion we do
-     the CRLF conversion anyway.  At least one source ZIP
-     file has this structure in its source code.
-
-     If every occurrance of a CR and LF is paired up as a
-     CRLF pair then the conversion is safely bi-directional.
-     s/\r\n/\n/g == s/\n/\r\\n/g can convert between them.
-  """
-  nul = data.find('\0')
-  if 0 <= nul and nul < (len(data) - 1):
-    return False
-
-  n_lf = 0
-  last = 0
-  while True:
-    lf = data.find('\n', last)
-    if lf < 0:
-      break
-    if lf == 0 or data[lf - 1] != '\r':
-      return False
-    last = lf + 1
-    n_lf += 1
-  return n_lf > 0
-
-class _ZipFile(object):
-  """Streaming iterator to parse a zip file on the fly.
-  """
-  def __init__(self, fd):
-    self._fd = _UngetStream(fd)
-
-  def FileRecords(self):
-    return _FileIter(self._fd)
-
-  def CentralDirectory(self):
-    return _CentIter(self._fd)
-
-  def CheckTail(self):
-    type_buf = self._fd.read(4)
-    type = struct.unpack('<I', type_buf)[0]
-    if type != 0x06054b50:  # end of central directory
-      raise ImportError('zip record %x unsupported' % type)
-
-  def Open(self, entry):
-    if entry.is_compressed:
-      return _InflateStream(self._fd)
-    else:
-      if entry.has_trailer:
-        raise ImportError('unable to extract streamed zip')
-      return _FixedLengthStream(self._fd, entry.uncompressed_size)
-
-  def Close(self, entry):
-    if entry.has_trailer:
-      type = struct.unpack('<I', self._fd.read(4))[0]
-      if type == 0x08074b50:
-        # Not a formal type marker, but commonly seen in zips
-        # as the data descriptor signature.
-        #
-        struct.unpack('<3I', self._fd.read(12))
-      else:
-        # No signature for the data descriptor, so read the
-        # remaining fields out of the stream
-        #
-        self._fd.read(8)
-
-
-class _FileIter(object):
-  def __init__(self, fd):
-    self._fd = fd
-
-  def __iter__(self):
-    return self
-
-  def next(self):
-    fd = self._fd
-
-    type_buf = fd.read(4)
-    type = struct.unpack('<I', type_buf)[0]
-
-    if type != 0x04034b50:    # local file header
-      fd.unread(type_buf)
-      raise StopIteration()
-
-    rec = _FileHeader(fd.read(26))
-    rec.name = fd.read(rec.name_len)
-    fd.read(rec.extra_len)
-
-    if rec.name.endswith('/'):
-      rec.name = rec.name[:-1]
-      rec.mode = stat.S_IFDIR | 0777
-    return rec
-
-
-class _FileHeader(object):
-  """Information about a single file in the archive.
-     0  version needed to extract       2 bytes
-     1  general purpose bit flag        2 bytes
-     2  compression method              2 bytes
-     3  last mod file time              2 bytes
-     4  last mod file date              2 bytes
-     5  crc-32                          4 bytes
-     6  compressed size                 4 bytes
-     7  uncompressed size               4 bytes
-     8  file name length                2 bytes
-     9  extra field length              2 bytes
-  """
-  def __init__(self, raw_bin):
-    rec = struct.unpack('<5H3I2H', raw_bin)
-    
-    if rec[2] == 8:
-      self.is_compressed = True
-    elif rec[2] == 0:
-      self.is_compressed = False
-    else:
-      raise ImportError('unrecognized compression format')
-
-    if rec[1] & (1 << 3):
-      self.has_trailer = True
-    else:
-      self.has_trailer = False
-
-    self.compressed_size  = rec[6]
-    self.uncompressed_size = rec[7]
-    self.name_len = rec[8]
-    self.extra_len = rec[9]
-    self.mode = stat.S_IFREG | 0644
-
-
-class _CentIter(object):
-  def __init__(self, fd):
-    self._fd = fd
-
-  def __iter__(self):
-    return self
-
-  def next(self):
-    fd = self._fd
-
-    type_buf = fd.read(4)
-    type = struct.unpack('<I', type_buf)[0]
-
-    if type != 0x02014b50:  # central directory
-      fd.unread(type_buf)
-      raise StopIteration()
-
-    rec = _CentHeader(fd.read(42))
-    rec.name = fd.read(rec.name_len)
-    fd.read(rec.extra_len)
-    fd.read(rec.comment_len)
-
-    if rec.name.endswith('/'):
-      rec.name = rec.name[:-1]
-      rec.mode = stat.S_IFDIR | 0777
-    return rec
-
-
-class _CentHeader(object):
-  """Information about a single file in the archive.
-     0  version made by                 2 bytes
-     1  version needed to extract       2 bytes
-     2  general purpose bit flag        2 bytes
-     3  compression method              2 bytes
-     4  last mod file time              2 bytes
-     5  last mod file date              2 bytes
-     6  crc-32                          4 bytes
-     7  compressed size                 4 bytes
-     8  uncompressed size               4 bytes
-     9  file name length                2 bytes
-    10  extra field length              2 bytes
-    11  file comment length             2 bytes
-    12  disk number start               2 bytes
-    13  internal file attributes        2 bytes
-    14  external file attributes        4 bytes
-    15  relative offset of local header 4 bytes
-  """
-  def __init__(self, raw_bin):
-    rec = struct.unpack('<6H3I5H2I', raw_bin)
-    self.name_len = rec[9]
-    self.extra_len = rec[10]
-    self.comment_len = rec[11]
-
-    if (rec[0] & 0xff00) == 0x0300:  # UNIX
-      self.mode = rec[14] >> 16
-    else:
-      self.mode = stat.S_IFREG | 0644
-
-
-class _UngetStream(object):
-  """File like object to read and rewind a stream.
-  """
-  def __init__(self, fd):
-    self._fd = fd
-    self._buf = None
-
-  def read(self, size = -1):
-    r = []
-    try:
-      if size >= 0:
-        self._ReadChunk(r, size)
-      else:
-        while True:
-          self._ReadChunk(r, 2048)
-    except EOFError:
-      pass
-
-    if len(r) == 1:
-      return r[0]
-    return ''.join(r)
-
-  def unread(self, buf):
-    b = self._buf
-    if b is None or len(b) == 0:
-      self._buf = buf
-    else:
-      self._buf = buf + b
-
-  def _ReadChunk(self, r, size):
-    b = self._buf
-    try:
-      while size > 0:
-        if b is None or len(b) == 0:
-          b = self._Inflate(self._fd.read(2048))
-          if not b:
-            raise EOFError()
-          continue
-
-        use = min(size, len(b))
-        r.append(b[:use])
-        b = b[use:]
-        size -= use
-    finally:
-      self._buf = b
-
-  def _Inflate(self, b):
-    return b
-
-
-class _FixedLengthStream(_UngetStream):
-  """File like object to read a fixed length stream.
-  """
-  def __init__(self, fd, have):
-    _UngetStream.__init__(self, fd)
-    self._have = have
-
-  def _Inflate(self, b):
-    n = self._have
-    if n == 0:
-      self._fd.unread(b)
-      return None
-
-    if len(b) > n:
-      self._fd.unread(b[n:])
-      b = b[:n]
-    self._have -= len(b)
-    return b
-
-
-class _InflateStream(_UngetStream):
-  """Inflates the stream as it reads input.
-  """
-  def __init__(self, fd):
-    _UngetStream.__init__(self, fd)
-    self._z = zlib.decompressobj(-zlib.MAX_WBITS)
-
-  def _Inflate(self, b):
-    z = self._z
-    if not z:
-      self._fd.unread(b)
-      return None
-
-    b = z.decompress(b)
-    if z.unconsumed_tail != '':
-      self._fd.unread(z.unconsumed_tail)
-    elif z.unused_data != '':
-      self._fd.unread(z.unused_data)
-      self._z = None
-    return b
diff --git a/manifest.py b/manifest.py
index 8c5a8d6..ffff14a 100644
--- a/manifest.py
+++ b/manifest.py
@@ -18,8 +18,6 @@
 import xml.dom.minidom
 
 from git_config import GitConfig, IsId
-from import_tar import ImportTar
-from import_zip import ImportZip
 from project import Project, MetaProject, R_TAGS
 from remote import Remote
 from error import ManifestParseError
@@ -245,78 +243,8 @@
       elif n.nodeName == 'copyfile':
         self._ParseCopyFile(project, n)
 
-    to_resolve = []
-    by_version = {}
-
-    for n in node.childNodes:
-      if n.nodeName == 'import':
-        self._ParseImport(project, n, to_resolve, by_version)
-
-    for pair in to_resolve:
-      sn, pr = pair
-      try:
-        sn.SetParent(by_version[pr].commit)
-      except KeyError:
-        raise ManifestParseError, \
-              'snapshot %s not in project %s in %s' % \
-              (pr, project.name, self.manifestFile)
-
     return project
 
-  def _ParseImport(self, project, import_node, to_resolve, by_version):
-    first_url = None
-    for node in import_node.childNodes:
-      if node.nodeName == 'mirror':
-        first_url = self._reqatt(node, 'url')
-        break
-    if not first_url:
-      raise ManifestParseError, \
-            'mirror url required for project %s in %s' % \
-            (project.name, self.manifestFile)
-
-    imp = None
-    for cls in [ImportTar, ImportZip]:
-      if cls.CanAccept(first_url):
-        imp = cls()
-        break
-    if not imp:
-      raise ManifestParseError, \
-            'snapshot %s unsupported for project %s in %s' % \
-            (first_url, project.name, self.manifestFile)
-
-    imp.SetProject(project)
-
-    for node in import_node.childNodes:
-      if node.nodeName == 'remap':
-        old = node.getAttribute('strip')
-        new = node.getAttribute('insert')
-        imp.RemapPath(old, new)
-
-      elif node.nodeName == 'mirror':
-        imp.AddUrl(self._reqatt(node, 'url'))
-
-    for node in import_node.childNodes:
-      if node.nodeName == 'snapshot':
-        sn = imp.Clone()
-        sn.SetVersion(self._reqatt(node, 'version'))
-        sn.SetCommit(node.getAttribute('check'))
-
-        pr = node.getAttribute('prior')
-        if pr:
-          if IsId(pr):
-            sn.SetParent(pr)
-          else:
-            to_resolve.append((sn, pr))
-
-        rev = R_TAGS + sn.TagName
-
-        if rev in project.snapshots:
-          raise ManifestParseError, \
-                'duplicate snapshot %s for project %s in %s' % \
-                (sn.version, project.name, self.manifestFile)
-        project.snapshots[rev] = sn
-        by_version[sn.version] = sn
-
   def _ParseCopyFile(self, project, node):
     src = self._reqatt(node, 'src')
     dest = self._reqatt(node, 'dest')
diff --git a/subcmds/compute_snapshot_check.py b/subcmds/compute_snapshot_check.py
deleted file mode 100644
index 82db359..0000000
--- a/subcmds/compute_snapshot_check.py
+++ /dev/null
@@ -1,169 +0,0 @@
-#
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import os
-import sys
-import tempfile
-
-from command import Command
-from error import GitError, NoSuchProjectError
-from git_config import IsId
-from import_tar import ImportTar
-from import_zip import ImportZip
-from project import Project
-from remote import Remote
-
-def _ToCommit(project, rev):
-  return project.bare_git.rev_parse('--verify', '%s^0' % rev)
-
-def _Missing(project, rev):
-  return project._revlist('--objects', rev, '--not', '--all')
-
-
-class ComputeSnapshotCheck(Command):
-  common = False
-  helpSummary = "Compute the check value for a new snapshot"
-  helpUsage = """
-%prog -p NAME -v VERSION -s FILE [options]
-"""
-  helpDescription = """
-%prog computes and then displays the proper check value for a
-snapshot, so it can be pasted into the manifest file for a project.
-"""
-
-  def _Options(self, p):
-    g = p.add_option_group('Snapshot description options')
-    g.add_option('-p', '--project',
-                 dest='project', metavar='NAME',
-                 help='destination project name')
-    g.add_option('-v', '--version',
-                 dest='version', metavar='VERSION',
-                 help='upstream version/revision identifier')
-    g.add_option('-s', '--snapshot',
-                 dest='snapshot', metavar='PATH',
-                 help='local tarball path')
-    g.add_option('--new-project',
-                 dest='new_project', action='store_true',
-                 help='destinition is a new project')
-    g.add_option('--keep',
-                 dest='keep_git', action='store_true',
-                 help='keep the temporary git repository')
-
-    g = p.add_option_group('Base revision grafting options')
-    g.add_option('--prior',
-                 dest='prior', metavar='COMMIT',
-                 help='prior revision checksum')
-
-    g = p.add_option_group('Path mangling options')
-    g.add_option('--strip-prefix',
-                 dest='strip_prefix', metavar='PREFIX',
-                 help='remove prefix from all paths on import')
-    g.add_option('--insert-prefix',
-                 dest='insert_prefix', metavar='PREFIX',
-                 help='insert prefix before all paths on import')
-
-
-  def _Compute(self, opt):
-    try:
-      real_project = self.GetProjects([opt.project])[0]
-    except NoSuchProjectError:
-      if opt.new_project:
-        print >>sys.stderr, \
-          "warning: project '%s' does not exist" % opt.project
-      else:
-        raise NoSuchProjectError(opt.project)
-
-    self._tmpdir = tempfile.mkdtemp()
-    project = Project(manifest = self.manifest,
-                      name = opt.project,
-                      remote = Remote('origin'),
-                      gitdir = os.path.join(self._tmpdir, '.git'),
-                      worktree = self._tmpdir,
-                      relpath = opt.project,
-                      revision = 'refs/heads/master')
-    project._InitGitDir()
-
-    url = 'file://%s' % os.path.abspath(opt.snapshot)
-
-    imp = None
-    for cls in [ImportTar, ImportZip]:
-      if cls.CanAccept(url):
-        imp = cls()
-        break
-    if not imp:
-      print >>sys.stderr, 'error: %s unsupported' % opt.snapshot
-      sys.exit(1)
-
-    imp.SetProject(project)
-    imp.SetVersion(opt.version)
-    imp.AddUrl(url)
-
-    if opt.prior:
-      if opt.new_project:
-        if not IsId(opt.prior):
-          print >>sys.stderr, 'error: --prior=%s not valid' % opt.prior
-          sys.exit(1)
-      else:
-        try:
-          opt.prior = _ToCommit(real_project, opt.prior)
-          missing = _Missing(real_project, opt.prior)
-        except GitError, e:
-          print >>sys.stderr,\
-            'error: --prior=%s not valid\n%s' \
-            % (opt.prior, e)
-          sys.exit(1)
-        if missing:
-          print >>sys.stderr,\
-            'error: --prior=%s is valid, but is not reachable' \
-            % opt.prior
-          sys.exit(1)
-      imp.SetParent(opt.prior)
-
-    src = opt.strip_prefix
-    dst = opt.insert_prefix
-    if src or dst:
-      if src is None:
-        src = ''
-      if dst is None:
-        dst = ''
-      imp.RemapPath(src, dst)
-    commitId = imp.Import()
-
-    print >>sys.stderr,"%s\t%s" % (commitId, imp.version)
-    return project
-
-  def Execute(self, opt, args):
-    if args \
-       or not opt.project \
-       or not opt.version \
-       or not opt.snapshot:
-      self.Usage()
-
-    success = False
-    project = None
-    try:
-      self._tmpdir = None
-      project = self._Compute(opt)
-    finally:
-      if project and opt.keep_git:
-        print 'GIT_DIR = %s' % (project.gitdir)
-      elif self._tmpdir:
-        for root, dirs, files in os.walk(self._tmpdir, topdown=False):
-          for name in files:
-            os.remove(os.path.join(root, name))
-          for name in dirs:
-            os.rmdir(os.path.join(root, name))
-        os.rmdir(self._tmpdir)
-
