docs: def _read_zip(self, filepath):
          """
          Read an IPS installation zipfile and return the core version number
          @type   filepath:   str
          @rtype: Version
          """
          with ZipFile(filepath) as zip:
              namelist = zip.namelist()
              if re.match(r'^ips_\w{5}/?$', namelist[0]):
                  self.log.debug('Setup directory matched: %s', namelist[0])
              else:
                  self.log.error('No setup directory matched')
                  raise BadZipfile('Unrecognized setup file format')
  
              versions_path = os.path.join(namelist[0], 'applications/core/data/versions.json')
              if versions_path not in namelist:
                  raise BadZipfile('Missing versions.json file')
              versions = json.loads(zip.read(versions_path), object_pairs_hook=OrderedDict)
              vid = next(reversed(versions))
              version = versions[vid]
  
              self.log.debug('Version matched: %s', version)
              return Version(version, vid)