/**
   * Constructor.
   *
   * @param codeBaseLocator the codebase locator for this codebase
   * @param file the File containing the zip file (may be a temp file if the codebase was copied
   *     from a nested zipfile in another codebase)
   */
  public ZipInputStreamCodeBase(ICodeBaseLocator codeBaseLocator, File file) throws IOException {
    super(codeBaseLocator);

    this.file = file;
    setLastModifiedTime(file.lastModified());
    ZipInputStream zis = new ZipInputStream(new FileInputStream(file));
    try {
      ZipEntry ze;

      if (DEBUG) {
        System.out.println("Reading zip input stream " + file);
      }

      while ((ze = zis.getNextEntry()) != null) {
        String name = ze.getName();
        if (!ze.isDirectory()
            && (name.equals("META-INF/MANIFEST.MF")
                || name.endsWith(".class")
                || Archive.isArchiveFileName(name))) {
          entries.add(name);
          if (name.equals("META-INF/MANIFEST.MF")) {
            map.put(name, build(zis, ze));
          }
        }
        zis.closeEntry();
      }
    } finally {
      zis.close();
    }
    if (DEBUG) {
      System.out.println("Done with zip input stream " + file);
    }
  }
  /* (non-Javadoc)
   * @see edu.umd.cs.findbugs.classfile.ICodeBase#lookupResource(java.lang.String)
   */
  public ICodeBaseEntry lookupResource(String resourceName) {

    // Translate resource name, in case a resource name
    // has been overridden and the resource is being accessed
    // using the overridden name.
    resourceName = translateResourceName(resourceName);
    if (!entries.contains(resourceName)) {
      return null;
    }

    try {
      ZipInputStreamCodeBaseEntry z = map.get(resourceName);
      if (z != null) {
        return z;
      }
      ZipInputStream zis = new ZipInputStream(new FileInputStream(file));
      try {
        ZipEntry ze;

        boolean found = false;
        int countDown = 20;
        while ((ze = zis.getNextEntry()) != null && countDown >= 0) {
          if (ze.getName().equals(resourceName)) {
            found = true;
          }
          if (found) {
            countDown--;
            if (map.containsKey(ze.getName())) {
              continue;
            }
            z = build(zis, ze);
            map.put(ze.getName(), z);
          }
          zis.closeEntry();
        }
      } finally {
        zis.close();
      }
      z = map.get(resourceName);
      if (z == null) {
        throw new AssertionError("Could not find " + resourceName);
      }
      return z;
    } catch (IOException e) {
      return null;
    }
  }