docs: @SuppressWarnings({"resource", "checkstyle:cyclomaticcomplexity", "checkstyle:npathcomplexity"})
  	protected synchronized void replaceInFile(File sourceFile, File targetFile, ReplacementType replacementType,
  			File[] classpath, boolean detectEncoding) throws MojoExecutionException {
  		final File outputFile;
  		final File inputFile;
  		assert targetFile != null;
  
  		if (sourceFile == null) {
  			inputFile = targetFile;
  			outputFile = new File(targetFile.getAbsolutePath() + ".maven.tmp"); //$NON-NLS-1$
  		} else {
  			inputFile = sourceFile;
  			outputFile = targetFile;
  		}
  
  		final BuildContext buildContext = getBuildContext();
  		buildContext.removeMessages(sourceFile);
  		buildContext.removeMessages(targetFile);
  
  		final ExtendedArtifact artifact = searchArtifact(inputFile);
  
  		final String filename = removePathPrefix(getBaseDirectory(), inputFile);
  
  		String shortFilename = null;
  		for (int i = 0; shortFilename == null && i < classpath.length; ++i) {
  			if (inputFile.getAbsolutePath().startsWith(classpath[i].getAbsolutePath())) {
  				shortFilename = removePathPrefix(classpath[i], inputFile);
  			}
  		}
  
  		if (artifact != null) {
  			getLog().debug("Replacing in " + filename + " with artifact " + //$NON-NLS-1$ //$NON-NLS-2$
  					ArtifactUtils.key(artifact));
  		} else {
  			getLog().debug("Replacing in " + filename + " without artifact"); //$NON-NLS-1$ //$NON-NLS-2$
  		}
  
  		try {
  			outputFile.getParentFile().mkdirs();
  			Reader reader = null;
  
  			Charset charset = null;
  
  			if (detectEncoding) {
  				charset = detectEncoding(inputFile);
  			}
  
  			if (charset == null) {
  				charset = Charset.defaultCharset();
  			}
  
  			getLog().debug("Copying file '" //$NON-NLS-1$
  					+ inputFile.getName() + "' with '" //$NON-NLS-1$
  					+ charset.displayName() + "' encoding"); //$NON-NLS-1$
  
  			try (FileInputStream fis = new FileInputStream(inputFile)) {
  				try (ReadableByteChannel channel = Channels.newChannel(fis)) {
  					reader = Channels.newReader(channel, charset.newDecoder(), -1);
  
  					if (reader == null) {
  						reader = new FileReader(inputFile);
  					}
  
  					final BufferedReader br = new BufferedReader(reader);
  					try (FileOutputStream fos = new FileOutputStream(outputFile)) {
  						final WritableByteChannel wChannel = Channels.newChannel(fos);
  						final Writer writer = Channels.newWriter(wChannel, charset.newEncoder(), -1);
  						String line;
  						int nline = 1;
  
  						while ((line = br.readLine()) != null) {
  							line = replaceInString(inputFile, nline, shortFilename, artifact, line, replacementType);
  							writer.write(line);
  							writer.write("\n"); //$NON-NLS-1$
  							++nline;
  						}
  						writer.flush();
  					}
  				}
  			}
  
  			if (sourceFile == null) {
  				fileCopy(outputFile, targetFile);
  				outputFile.delete();
  				buildContext.refresh(outputFile.getParentFile());
  			}
  		} catch (IOException e) {
  			throw new MojoExecutionException(e.getLocalizedMessage(), e);
  		} finally {
  			if (sourceFile == null && outputFile.exists()) {
  				outputFile.delete();
  				buildContext.refresh(outputFile.getParentFile());
  			} else if (outputFile.exists()) {
  				buildContext.refresh(outputFile);
  			}
  		}
  	}