class FoundFile implements IFoundFile {
  private static final Logger logger = LoggerFactory.getLogger(FoundFile.class);

  protected final List<InputStream> openedInputStreams = new ArrayList<InputStream>();

  protected Path path;

  protected File file;
  protected String entryName;

  protected SharedCloseable<ZipFile> zipFile;
  protected ZipEntry zipEntry;

  public FoundFile(String archivePath, String entryName) {
    if (archivePath == null || entryName == null) {
      throw new IllegalArgumentException("Error: The archive path and entry name cannot be null.");
    }
    this.file = new File(archivePath);
    this.entryName = entryName;
  }

  public FoundFile(File file) {
    if (file == null) {
      throw new IllegalArgumentException("Error: The file cannot be null.");
    }
    this.file = file;
    this.entryName = null;
  }

  public FoundFile(Path path) {
    this.path = path;
  }

  @Override
  public String getFilePath() {
    if (file == null) {
      if (path != null) {
        File f = path.toFile();
        if (f != null) {
          return f.getPath();
        }
      }
      return null;
    }
    return file.getPath();
  }

  @Override
  public boolean isZipFile() {
    return entryName != null;
  }

  @Override
  public ZipFile getZipFile() {
    return zipFile != null ? zipFile.get() : null;
  }

  @Override
  public File getFile() {
    return file;
  }

  @Override
  public String getAbsolutePath() {
    try {
      return file != null ? file.getCanonicalPath() : path.toRealPath().toString();
    } catch (IOException ex) {
      return file != null ? file.getAbsolutePath() : path.toAbsolutePath().toString();
    }
  }

  @Override
  public InputStream inputStream() {<FILL_FUNCTION_BODY>}

  @Override
  public void close() {
    // Try to close all opened input streams
    List<Exception> errs = new ArrayList<Exception>(0);
    for (InputStream is : openedInputStreams) {
      try {
        is.close();
      } catch (Exception e) {
        errs.add(e);// record errors for later
      }
    }
    openedInputStreams.clear();
    closeZipFile(errs);

    // Throw single exception combining all errors
    if (!errs.isEmpty()) {
      String msg = null;
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      try (PrintStream ps = new PrintStream(baos, true, "utf-8")) {
        ps.println("Error: Failed to close all opened resources. The following exceptions were thrown in the process: ");
        int i = 0;
        for (Throwable t : errs) {
          ps.print("Exception ");
          ps.print(i++);
          ps.print(": ");
          logger.error(t.getMessage(), t);
        }
        msg = new String(baos.toByteArray(), StandardCharsets.UTF_8);
      } catch (Exception e) {
        // Do nothing as this will never occur
      }
      throw new RuntimeException(msg);
    }
  }

  protected void closeZipFile(List<Exception> errs) {
    // Try to close the opened zip file if it exists
    if (zipFile != null) {
      try {
        zipFile.close();
        errs.clear();// Successfully closed the archive so all input
        // streams were closed successfully also
      } catch (Exception e) {
        errs.add(e);
      }
      zipFile = null;// set to null no matter what
      zipEntry = null;// set to null no matter what
    }
  }

  private static InputStream doJDKBugWorkaround(InputStream is, long size) throws IOException {
    int sz = (int) size;
    final byte[] buf = new byte[sz];
    final int N = 1024;
    for (int ln = 0, count = 0; sz > 0 && (ln = is.read(buf, count, Math.min(N, sz))) != -1;) {
      count += ln;
      sz -= ln;
    }
    return new ByteArrayInputStream(buf);
  }
}

    InputStream ret = null;
    if (path != null) {
      try {
        ret = Files.newInputStream(path);
      } catch (IOException e) {
        throw new RuntimeException(
            "Error: Failed to open a InputStream for the file at path '" + path.toAbsolutePath().toString() + "'.", e);
      }
    } else if (!isZipFile()) {
      try {
        ret = new FileInputStream(file);
      } catch (Exception e) {
        throw new RuntimeException("Error: Failed to open a InputStream for the file at path '" + file.getPath() + "'.", e);
      }
    } else {
      if (zipFile == null) {
        try {
          zipFile = SourceLocator.v().archivePathToZip.getRef(file.getPath());
          zipEntry = zipFile.get().getEntry(entryName);
          if (zipEntry == null) {
            silentClose();
            throw new RuntimeException(
                "Error: Failed to find entry '" + entryName + "' in the archive file at path '" + file.getPath() + "'.");
          }
        } catch (Exception e) {
          silentClose();
          throw new RuntimeException(
              "Error: Failed to open the archive file at path '" + file.getPath() + "' for entry '" + entryName + "'.", e);
        }
      }
      try (InputStream stream = zipFile.get().getInputStream(zipEntry)) {
        ret = doJDKBugWorkaround(stream, zipEntry.getSize());
      } catch (Exception e) {
        throw new RuntimeException("Error: Failed to open a InputStream for the entry '" + zipEntry.getName()
            + "' of the archive at path '" + zipFile.get().getName() + "'.", e);
      }
    }

    ret = new BufferedInputStream(ret);
    openedInputStreams.add(ret);
    return ret;
  
<no_super_class>