docs: @Override
      public InputStream getInputStream() throws IOException {
          if ( (zipEntryData == null) || zipEntryData.isDirectory() ) {
              return null;
          }
  
          final ZipFileHandle zipFileHandle = rootContainer.getZipFileHandle(); // throws IOException
  
          ZipFile zipFile = zipFileHandle.open();
  
          // The open must have a balancing close.  That should be done by the caller.
          // In the worst case, 'finalize' makes sure it happens.
  
          final InputStream baseInputStream;
          try {
              baseInputStream = zipFileHandle.getInputStream( zipFile, zipEntryData.getPath() ); // throws IOException
          } catch ( Throwable th ) {
              // Need to close here, since the caller never receives a wrapped
              // input stream to close.
              zipFileHandle.close();
              throw th;
          }
  
          if ( baseInputStream == null ) {
          	throw new FileNotFoundException(
          		"Zip file [ " + zipFile.getName() + " ]" +
          		" failed to provide input stream for entry [ " + zipEntryData.getPath() + " ]");
          }
  
          InputStream inputStream = new InputStream() {
              private final InputStream wrappedInputStream = baseInputStream;
  
              // Object lifecycle ...
  
              @Override
              public synchronized void finalize() throws Throwable {
                  close(); // throws IOException
  
                  super.finalize(); // throws Throwable
              }
  
              // Close ...
  
              private volatile boolean isClosed;
  
              @Override
              public void close() throws IOException {
                  if ( !isClosed ) {
                      synchronized( this ) {
                          if ( !isClosed ) {
                              try {
                                  wrappedInputStream.close(); // throws IOException
                              } catch ( IOException e ) {
                                  // FFDC
                              }
                              zipFileHandle.close();
                              isClosed = true;
                          }
                      }
                  }
              }
  
              // Delegate methods ...
  
              @Trivial
              @Override
              public int read(byte[] b) throws IOException {
                  return wrappedInputStream.read(b);
              }
  
              @Trivial
              @Override
              public int read(byte[] b, int off, int len) throws IOException {
                  return wrappedInputStream.read(b, off, len); // throws IOException
              }
  
              @Trivial
              @Override
              public long skip(long n) throws IOException {
                  return wrappedInputStream.skip(n); // throws IOException
              }
  
              @Trivial
              @Override
              public int available() throws IOException {
                  return wrappedInputStream.available(); // throws IOException
              }
  
              @SuppressWarnings("sync-override")
              @Trivial
              @Override
              public void mark(int readlimit) {
                  wrappedInputStream.mark(readlimit);
              }
  
              @SuppressWarnings("sync-override")
              @Trivial
              @Override
              public void reset() throws IOException {
                  wrappedInputStream.reset(); // throws IOException
              }
  
              @Trivial
              @Override
              public boolean markSupported() {
                  return wrappedInputStream.markSupported();
              }
  
              @Override
              public int read() throws IOException {
                  return wrappedInputStream.read(); // throws IOException
              }
          };
  
          return inputStream;
      }