class IcapClient implements Closeable {

  public boolean scanFile(final String filename) throws IcapException {
    if (filename == null || filename.trim().isEmpty()) {
      throw new IllegalArgumentException("Filename must not be empty");
    }
    if (client == null) {
      connect();
    }
    if (finalResult != null) {
      finalResult.clear();
      finalResult = null;
    }
    InputStream inputStream = null;
    final long length;
    if (EICARTEST.equals(filename)) {
      // Special file to test from EICAR Test file
      final ClassLoader classLoader = IcapClient.class.getClassLoader();
      final File fileSrc1 =
          new File(classLoader.getResource("eicar.com-part1.txt").getFile());
      final File fileSrc2 =
          new File(classLoader.getResource("eicar.com-part2.txt").getFile());
      if (fileSrc1.exists() && fileSrc2.exists()) {
        try {
          final byte[] array1 = Files.toByteArray(fileSrc1);
          final byte[] array2 = Files.toByteArray(fileSrc2);
          final byte[] array =
              Arrays.copyOf(array1, array1.length + array2.length);
          System.arraycopy(array2, 0, array, array1.length, array2.length);
          inputStream = new ByteArrayInputStream(array);
          length = array.length;
        } catch (final IOException e) {
          logger.error("File EICAR TEST does not exist", e);
          throw new IcapException("File EICAR TEST cannot be found",
                                  IcapError.ICAP_ARGUMENT_ERROR);
        }
      } else {
        logger.error("File EICAR TEST does not exist");
        throw new IcapException("File EICAR TEST cannot be found",
                                IcapError.ICAP_ARGUMENT_ERROR);
      }
    } else {
      final File file = new File(filename);
      if (!file.canRead()) {
        logger.error("File does not exist: {}", file.getAbsolutePath());
        throw new IcapException(
            "File cannot be found: " + file.getAbsolutePath(),
            IcapError.ICAP_ARGUMENT_ERROR);
      }
      length = file.length();
      if (length > maxSize) {
        logger.error("File size {} exceed limit of {}: {}", length, maxSize,
                     file.getAbsolutePath());
        throw new IcapException(
            "File exceed limit size: " + file.getAbsolutePath(),
            IcapError.ICAP_FILE_LENGTH_ERROR);
      }
      try {
        inputStream = new FileInputStream(file);
      } catch (final FileNotFoundException e) {
        logger
            .error("Could not find file {} since {}", filename, e.getMessage());
        throw new IcapException("File cannot be found: " + filename, e,
                                IcapError.ICAP_ARGUMENT_ERROR);
      }
    }
    try {
      return scanFile(filename, inputStream, length);
    } finally {
      if (inputStream != null) {
        try {
          inputStream.close();
        } catch (final IOException ignored) {
          // Nothing
        }
      }
      close();
    }
  }

  public  IcapClient(final String serverIP, final int port,
                    final String icapService);
  public  IcapClient(final String serverIP, final int port,
                    final String icapService, final int previewSize);

}