docs: private Resource newResource(final String relativePath, final File classpathResourceFile) {
          return new Resource(this, classpathResourceFile.length()) {
              /** The random access file. */
              private RandomAccessFile randomAccessFile;
  
              /** The file channel. */
              private FileChannel fileChannel;
  
              @Override
              public String getPath() {
                  return relativePath;
              }
  
              @Override
              public String getPathRelativeToClasspathElement() {
                  return relativePath;
              }
  
              @Override
              public synchronized ByteBuffer read() throws IOException {
                  if (skipClasspathElement) {
                      // Shouldn't happen
                      throw new IOException("Parent directory could not be opened");
                  }
                  markAsOpen();
                  try {
                      randomAccessFile = new RandomAccessFile(classpathResourceFile, "r");
                      fileChannel = randomAccessFile.getChannel();
                      MappedByteBuffer buffer = null;
                      try {
                          buffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fileChannel.size());
                      } catch (final FileNotFoundException e) {
                          throw e;
                      } catch (IOException | OutOfMemoryError e) {
                          // If map failed, try calling System.gc() to free some allocated MappedByteBuffers
                          // (there is a limit to the number of mapped files -- 64k on Linux)
                          // See: http://www.mapdb.org/blog/mmap_files_alloc_and_jvm_crash/
                          System.gc();
                          // Then try calling map again
                          buffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fileChannel.size());
                      }
                      byteBuffer = buffer;
                      length = byteBuffer.remaining();
                      return byteBuffer;
                  } catch (final IOException | SecurityException | OutOfMemoryError e) {
                      close();
                      throw new IOException("Could not open " + this, e);
                  }
              }
  
              @Override
              synchronized InputStreamOrByteBufferAdapter openOrRead() throws IOException {
                  if (length >= FileUtils.FILECHANNEL_FILE_SIZE_THRESHOLD) {
                      return new InputStreamOrByteBufferAdapter(read());
                  } else {
                      return new InputStreamOrByteBufferAdapter(inputStream = new InputStreamResourceCloser(this,
                              Files.newInputStream(classpathResourceFile.toPath())));
                  }
              }
  
              @Override
              public synchronized InputStream open() throws IOException {
                  if (length >= FileUtils.FILECHANNEL_FILE_SIZE_THRESHOLD) {
                      read();
                      return inputStream = new InputStreamResourceCloser(this, byteBufferToInputStream());
                  } else {
                      markAsOpen();
                      try {
                          return inputStream = new InputStreamResourceCloser(this,
                                  Files.newInputStream(classpathResourceFile.toPath()));
                      } catch (final IOException | SecurityException e) {
                          close();
                          throw new IOException("Could not open " + this, e);
                      }
                  }
              }
  
              @Override
              public synchronized byte[] load() throws IOException {
                  try {
                      final byte[] byteArray;
                      if (length >= FileUtils.FILECHANNEL_FILE_SIZE_THRESHOLD) {
                          read();
                          byteArray = byteBufferToByteArray();
                      } else {
                          open();
                          byteArray = FileUtils.readAllBytesAsArray(inputStream, length);
                      }
                      length = byteArray.length;
                      return byteArray;
                  } finally {
                      close();
                  }
              }
  
              @Override
              public synchronized void close() {
                  super.close(); // Close inputStream
                  if (byteBuffer != null) {
                      FileUtils.closeDirectByteBuffer(byteBuffer, /* log = */ null);
                      byteBuffer = null;
                  }
                  if (fileChannel != null) {
                      try {
                          fileChannel.close();
                      } catch (final IOException e) {
                          // Ignore
                      }
                      fileChannel = null;
                  }
                  if (randomAccessFile != null) {
                      try {
                          randomAccessFile.close();
                      } catch (final IOException e) {
                          // Ignore
                      }
                      randomAccessFile = null;
                  }
                  markAsClosed();
              }
          };
      }