docs: @SuppressWarnings("checkstyle:npathcomplexity")
  	public final Charset detectEncoding(File file) {
  		final Collection<Charset> fittingCharsets = new TreeSet<>();
  		for (final Charset c : Charset.availableCharsets().values()) {
  			final CharsetDecoder decoder = c.newDecoder();
  			try {
  				detectEncoding(file, decoder);
  				fittingCharsets.add(c);
  			} catch (Throwable e) {
  				//
  			}
  		}
  		if (getLog().isDebugEnabled()) {
  			getLog().debug("Valid charsets for " + file.getName() + ":\n" //$NON-NLS-1$ //$NON-NLS-2$
  					+ fittingCharsets.toString());
  		}
  
  		for (final Charset prefCharset : getPreferredCharsets()) {
  			if (prefCharset.canEncode() && fittingCharsets.contains(prefCharset)) {
  				getLog().debug("Use preferred charset for " + file.getName() //$NON-NLS-1$
  						+ ": " + prefCharset.displayName()); //$NON-NLS-1$
  				return prefCharset;
  			}
  		}
  
  		final Charset platformCharset = Charset.defaultCharset();
  
  		if (platformCharset.canEncode() && fittingCharsets.contains(platformCharset)) {
  			getLog().debug("Use platform default charset for " + file.getName() + ": " //$NON-NLS-1$ //$NON-NLS-2$
  					+ platformCharset.displayName());
  			return Charset.defaultCharset();
  		}
  
  		final Iterator<Charset> iterator = fittingCharsets.iterator();
  		while (iterator.hasNext()) {
  			final Charset c = iterator.next();
  			if (c.canEncode()) {
  				getLog().debug("Use first valid charset for " + file.getName() + ": " //$NON-NLS-1$ //$NON-NLS-2$
  						+ c.displayName());
  				return c;
  			}
  		}
  
  		return null;
  	}