class ArrayByteSource extends BeanByteSource implements ImmutableBean, Serializable {

  public static ArrayByteSource from(ByteSource other) {
    if (other instanceof ArrayByteSource) {
      return (ArrayByteSource) other;
    }
    String fileName = null;
    if (other instanceof BeanByteSource) {
      fileName = ((BeanByteSource) other).getFileName().orElse(null);

    } else if (other.getClass().getName().equals("com.google.common.io.ByteSource$ByteArrayByteSource")) {
      // extract the byte[] without using reflection
      // if the Guava implementation changes this could break, but that seems unlikely
      ByteProcessor<byte[]> processor = new ByteProcessor<byte[]>() {
        private byte[] captured;

        @Override
        public boolean processBytes(byte[] buf, int off, int len) throws IOException {
          if (captured != null) {
            // this defends against the Guava implementation being changed
            captured = Bytes.concat(captured, Arrays.copyOfRange(buf, off, off + len));
          } else if (off == 0 && len == buf.length) {
            // this is the normal case where we can just assign the source
            captured = buf;
          } else {
            // this happens if the source has been sliced
            captured = Arrays.copyOfRange(buf, off, off + len);
          }
          return true;
        }

        @Override
        public byte[] getResult() {
          return captured;
        }
      };
      return Unchecked.wrap(() -> new ArrayByteSource(other.read(processor)));

    } else {
      // handle all other byte sources
      String str = other.toString();
      if (str.equals("ByteSource.empty()")) {
        return EMPTY;
      } else if (str.startsWith("Files.asByteSource(")) {
        // extract the file name from toString()
        int pos = str.indexOf(')', 19);
        fileName = Paths.get(str.substring(19, pos)).getFileName().toString();
      } else if (str.startsWith("MoreFiles.asByteSource(")) {
        // extract the path name from toString()
        int pos = str.indexOf(',', 23);
        fileName = Paths.get(str.substring(23, pos)).getFileName().toString();
      } else if (str.startsWith("Resources.asByteSource(")) {
        // extract the URI from toString()
        int pos = str.indexOf(')', 23);
        String path = str.substring(23, pos);
        int lastSlash = path.lastIndexOf('/');
        fileName = path.substring(lastSlash + 1);
      }
    }
    return new ArrayByteSource(Unchecked.wrap(() -> other.read()), fileName);
  }

  private  ArrayByteSource(byte[] array);
    ArrayByteSource(byte[] array, String fileName);

}