_tryToAdd(
		compilation,
		config,
		module,
		runtime,
		activeRuntime,
		possibleModules,
		candidates,
		failureCache,
		chunkGraph,
		avoidMutateOnFailure,
		statistics
	) {
		const cacheEntry = failureCache.get(module);
		if (cacheEntry) {
			statistics.cached++;
			return cacheEntry;
		}

		// Already added?
		if (config.has(module)) {
			statistics.alreadyInConfig++;
			return null;
		}

		// Not possible to add?
		if (!possibleModules.has(module)) {
			statistics.invalidModule++;
			failureCache.set(module, module); // cache failures for performance
			return module;
		}

		// Module must be in the correct chunks
		const missingChunks = Array.from(
			chunkGraph.getModuleChunksIterable(config.rootModule)
		).filter(chunk => !chunkGraph.isModuleInChunk(module, chunk));
		if (missingChunks.length > 0) {
			/**
			 * @param {RequestShortener} requestShortener request shortener
			 * @returns {string} problem description
			 */
			const problem = requestShortener => {
				const missingChunksList = Array.from(
					new Set(missingChunks.map(chunk => chunk.name || "unnamed chunk(s)"))
				).sort();
				const chunks = Array.from(
					new Set(
						Array.from(chunkGraph.getModuleChunksIterable(module)).map(
							chunk => chunk.name || "unnamed chunk(s)"
						)
					)
				).sort();
				return `Module ${module.readableIdentifier(
					requestShortener
				)} is not in the same chunk(s) (expected in chunk(s) ${missingChunksList.join(
					", "
				)}, module is in chunk(s) ${chunks.join(", ")})`;
			};
			statistics.incorrectChunks++;
			failureCache.set(module, problem); // cache failures for performance
			return problem;
		}

		const moduleGraph = compilation.moduleGraph;

		const incomingConnections =
			moduleGraph.getIncomingConnectionsByOriginModule(module);

		const incomingConnectionsFromNonModules =
			incomingConnections.get(null) || incomingConnections.get(undefined);
		if (incomingConnectionsFromNonModules) {
			const activeNonModulesConnections =
				incomingConnectionsFromNonModules.filter(connection =>
					// We are not interested in inactive connections
					// or connections without dependency
					connection.isActive(runtime)
				);
			if (activeNonModulesConnections.length > 0) {
				/**
				 * @param {RequestShortener} requestShortener request shortener
				 * @returns {string} problem description
				 */
				const problem = requestShortener => {
					const importingExplanations = new Set(
						activeNonModulesConnections.map(c => c.explanation).filter(Boolean)
					);
					const explanations = Array.from(importingExplanations).sort();
					return `Module ${module.readableIdentifier(
						requestShortener
					)} is referenced ${
						explanations.length > 0
							? `by: ${explanations.join(", ")}`
							: "in an unsupported way"
					}`;
				};
				statistics.incorrectDependency++;
				failureCache.set(module, problem); // cache failures for performance
				return problem;
			}
		}

		/** @type {Map<Module, readonly ModuleGraph.ModuleGraphConnection[]>} */
		const incomingConnectionsFromModules = new Map();
		for (const [originModule, connections] of incomingConnections) {
			if (originModule) {
				// Ignore connection from orphan modules
				if (chunkGraph.getNumberOfModuleChunks(originModule) === 0) continue;

				// We don't care for connections from other runtimes
				let originRuntime;
				for (const r of chunkGraph.getModuleRuntimes(originModule)) {
					originRuntime = mergeRuntimeOwned(originRuntime, r);
				}

				if (!intersectRuntime(runtime, originRuntime)) continue;

				// We are not interested in inactive connections
				const activeConnections = connections.filter(connection =>
					connection.isActive(runtime)
				);
				if (activeConnections.length > 0)
					incomingConnectionsFromModules.set(originModule, activeConnections);
			}
		}

		const incomingModules = Array.from(incomingConnectionsFromModules.keys());

		// Module must be in the same chunks like the referencing module
		const otherChunkModules = incomingModules.filter(originModule => {
			for (const chunk of chunkGraph.getModuleChunksIterable(
				config.rootModule
			)) {
				if (!chunkGraph.isModuleInChunk(originModule, chunk)) {
					return true;
				}
			}
			return false;
		});
		if (otherChunkModules.length > 0) {
			/**
			 * @param {RequestShortener} requestShortener request shortener
			 * @returns {string} problem description
			 */
			const problem = requestShortener => {
				const names = otherChunkModules
					.map(m => m.readableIdentifier(requestShortener))
					.sort();
				return `Module ${module.readableIdentifier(
					requestShortener
				)} is referenced from different chunks by these modules: ${names.join(
					", "
				)}`;
			};
			statistics.incorrectChunksOfImporter++;
			failureCache.set(module, problem); // cache failures for performance
			return problem;
		}

		/** @type {Map<Module, readonly ModuleGraph.ModuleGraphConnection[]>} */
		const nonHarmonyConnections = new Map();
		for (const [originModule, connections] of incomingConnectionsFromModules) {
			const selected = connections.filter(
				connection =>
					!connection.dependency ||
					!(connection.dependency instanceof HarmonyImportDependency)
			);
			if (selected.length > 0)
				nonHarmonyConnections.set(originModule, connections);
		}
		if (nonHarmonyConnections.size > 0) {
			/**
			 * @param {RequestShortener} requestShortener request shortener
			 * @returns {string} problem description
			 */
			const problem = requestShortener => {
				const names = Array.from(nonHarmonyConnections)
					.map(
						([originModule, connections]) =>
							`${originModule.readableIdentifier(
								requestShortener
							)} (referenced with ${Array.from(
								new Set(
									connections
										.map(c => c.dependency && c.dependency.type)
										.filter(Boolean)
								)
							)
								.sort()
								.join(", ")})`
					)
					.sort();
				return `Module ${module.readableIdentifier(
					requestShortener
				)} is referenced from these modules with unsupported syntax: ${names.join(
					", "
				)}`;
			};
			statistics.incorrectModuleDependency++;
			failureCache.set(module, problem); // cache failures for performance
			return problem;
		}

		if (runtime !== undefined && typeof runtime !== "string") {
			// Module must be consistently referenced in the same runtimes
			/** @type {{ originModule: Module, runtimeCondition: RuntimeSpec }[]} */
			const otherRuntimeConnections = [];
			outer: for (const [
				originModule,
				connections
			] of incomingConnectionsFromModules) {
				/** @type {false | RuntimeSpec} */
				let currentRuntimeCondition = false;
				for (const connection of connections) {
					const runtimeCondition = filterRuntime(runtime, runtime =>
						connection.isTargetActive(runtime)
					);
					if (runtimeCondition === false) continue;
					if (runtimeCondition === true) continue outer;
					currentRuntimeCondition =
						currentRuntimeCondition !== false
							? mergeRuntime(currentRuntimeCondition, runtimeCondition)
							: runtimeCondition;
				}
				if (currentRuntimeCondition !== false) {
					otherRuntimeConnections.push({
						originModule,
						runtimeCondition: currentRuntimeCondition
					});
				}
			}
			if (otherRuntimeConnections.length > 0) {
				/**
				 * @param {RequestShortener} requestShortener request shortener
				 * @returns {string} problem description
				 */
				const problem = requestShortener =>
					`Module ${module.readableIdentifier(
						requestShortener
					)} is runtime-dependent referenced by these modules: ${Array.from(
						otherRuntimeConnections,
						({ originModule, runtimeCondition }) =>
							`${originModule.readableIdentifier(
								requestShortener
							)} (expected runtime ${runtimeToString(
								runtime
							)}, module is only referenced in ${runtimeToString(
								/** @type {RuntimeSpec} */ (runtimeCondition)
							)})`
					).join(", ")}`;
				statistics.incorrectRuntimeCondition++;
				failureCache.set(module, problem); // cache failures for performance
				return problem;
			}
		}

		let backup;
		if (avoidMutateOnFailure) {
			backup = config.snapshot();
		}

		// Add the module
		config.add(module);

		incomingModules.sort(compareModulesByIdentifier);

		// Every module which depends on the added module must be in the configuration too.
		for (const originModule of incomingModules) {
			const problem = this._tryToAdd(
				compilation,
				config,
				originModule,
				runtime,
				activeRuntime,
				possibleModules,
				candidates,
				failureCache,
				chunkGraph,
				false,
				statistics
			);
			if (problem) {
				if (backup !== undefined) config.rollback(backup);
				statistics.importerFailed++;
				failureCache.set(module, problem); // cache failures for performance
				return problem;
			}
		}

		// Add imports to possible candidates list
		for (const imp of this._getImports(compilation, module, runtime)) {
			candidates.add(imp);
		}
		statistics.added++;
		return null;
	}
@param {Compilation} compilation webpack compilation
@param {ConcatConfiguration} config concat configuration (will be modified when added)
@param {Module} module the module to be added
@param {RuntimeSpec} runtime the runtime scope of the generated code
@param {RuntimeSpec} activeRuntime the runtime scope of the root module
@param {Set<Module>} possibleModules modules that are candidates
@param {Set<Module>} candidates list of potential candidates (will be added to)
@param {Map<Module, Module | ((requestShortener: RequestShortener) => string)>} failureCache cache for problematic modules to be more performant
@param {ChunkGraph} chunkGraph the chunk graph
@param {boolean} avoidMutateOnFailure avoid mutating the config when adding fails
@param {Statistics} statistics gathering metrics
@returns {null | Module | ((requestShortener: RequestShortener) => string)} the problematic module