public static Iterator<Object[]> unzip(final byte[] a) {
    // can I tell the difference between a tar and zip here?
    final ZipInputStream dis = new ZipInputStream(new ByteArrayInputStream(a));
    
    return new Iterator<Object[]>() {
      ZipEntry gne() {
        try { return dis.getNextEntry(); } catch(IOException iox) { return null; }
      }
      @Override public void remove() {
        throw new RuntimeException("Iterator.remove not implemented");
      }
      @Override public boolean hasNext() {
        try { return dis.available() > 0; }
        catch(IOException iox) { return false; }
      }
      
      @Override public Object[] next() {
        ZipEntry z = gne();
        if (z == null) return null;
        while(z.isDirectory()) { z = gne(); if (z == null) return null; } 
        String s = z.getName();
        Object[] result = new Object[2];
        result[0] = s;
        long n = z.getSize();
        byte[] buf;
        if ( n == -1) {
          ByteArrayOutputStream bos = new ByteArrayOutputStream();
          try { while(dis.available() == 1) { bos.write(dis.read()); } } catch(IOException iox) { return null; }
          buf = bos.toByteArray();
        } else { 
          buf = new byte[(int)n];
          try { dis.read(buf); } catch(IOException iox) { }
        }
        result[1] = buf;
        return result;
      }
    };
  }