docs: @SuppressWarnings("static-method")
  	protected Collection<DynamicValidationComponent> createLocalFileValidatorComponents(Link it, URL url, int lineno,
  			File currentFile, DynamicValidationContext context) {
  		File fn = FileSystem.convertURLToFile(url);
  		if (Strings.isEmpty(fn.getName())) {
  			// Special case: the URL should point to a anchor in the current document.
  			final String linkRef = url.getRef();
  			if (!Strings.isEmpty(linkRef)) {
  				return Arrays.asList(new DynamicValidationComponent() {
  					@Override
  					public String functionName() {
  						return "Documentation_reference_anchor_test_" + lineno + "_"; //$NON-NLS-1$ //$NON-NLS-2$
  					}
  
  					@Override
  					public void generateValidationCode(ITreeAppendable it) {
  						context.setTempResourceRoots(null);
  						context.appendTitleAnchorExistenceTest(it, currentFile,
  								url.getRef(),
  								SECTION_PATTERN_TITLE_EXTRACTOR,
  								Iterables.concat(
  										Arrays.asList(MARKDOWN_FILE_EXTENSIONS),
  										Arrays.asList(HTML_FILE_EXTENSIONS)));
  					}
  				});
  			}
  			// No need to validate the current file's existency and anchor.
  			return null;
  		}
  		if (!fn.isAbsolute()) {
  			fn = FileSystem.join(currentFile.getParentFile(), fn);
  		}
  		final File filename = fn;
  		final String extension = FileSystem.extension(filename);
  		if (isMarkdownFileExtension(extension) || isHtmlFileExtension(extension)) {
  			// Special case: the file may be a HTML or a Markdown file.
  			final DynamicValidationComponent existence = new DynamicValidationComponent() {
  				@Override
  				public String functionName() {
  					return "Documentation_reference_test_" + lineno + "_"; //$NON-NLS-1$ //$NON-NLS-2$
  				}
  
  				@Override
  				public void generateValidationCode(ITreeAppendable it) {
  					context.setTempResourceRoots(context.getSourceRoots());
  					context.appendFileExistenceTest(it, filename, Messages.MarkdownParser_1,
  							Iterables.concat(
  									Arrays.asList(MARKDOWN_FILE_EXTENSIONS),
  									Arrays.asList(HTML_FILE_EXTENSIONS)));
  				}
  			};
  			if (!Strings.isEmpty(url.getRef())) {
  				final DynamicValidationComponent refValidity = new DynamicValidationComponent() {
  					@Override
  					public String functionName() {
  						return "Documentation_reference_anchor_test_" + lineno + "_"; //$NON-NLS-1$ //$NON-NLS-2$
  					}
  
  					@Override
  					public void generateValidationCode(ITreeAppendable it) {
  						context.setTempResourceRoots(null);
  						context.appendTitleAnchorExistenceTest(it, filename,
  								url.getRef(),
  								SECTION_PATTERN_TITLE_EXTRACTOR,
  								Iterables.concat(
  										Arrays.asList(MARKDOWN_FILE_EXTENSIONS),
  										Arrays.asList(HTML_FILE_EXTENSIONS)));
  					}
  				};
  				return Arrays.asList(existence, refValidity);
  			}
  			return Collections.singleton(existence);
  		}
  		return Arrays.asList(new DynamicValidationComponent() {
  			@Override
  			public String functionName() {
  				return "File_reference_test_" + lineno + "_"; //$NON-NLS-1$ //$NON-NLS-2$
  			}
  
  			@Override
  			public void generateValidationCode(ITreeAppendable it) {
  				context.appendFileExistenceTest(it, filename, Messages.MarkdownParser_1);
  			}
  		});
  	}