create(data, callback) {
		const context = data.context;
		const dependencies = data.dependencies;
		const resolveOptions = data.resolveOptions;
		const dependency = /** @type {ContextDependency} */ (dependencies[0]);
		const fileDependencies = new LazySet();
		const missingDependencies = new LazySet();
		const contextDependencies = new LazySet();
		this.hooks.beforeResolve.callAsync(
			{
				context,
				dependencies,
				layer: data.contextInfo.issuerLayer,
				resolveOptions,
				fileDependencies,
				missingDependencies,
				contextDependencies,
				...dependency.options
			},
			(err, beforeResolveResult) => {
				if (err) {
					return callback(err, {
						fileDependencies,
						missingDependencies,
						contextDependencies
					});
				}

				// Ignored
				if (!beforeResolveResult) {
					return callback(null, {
						fileDependencies,
						missingDependencies,
						contextDependencies
					});
				}

				const context = beforeResolveResult.context;
				const request = beforeResolveResult.request;
				const resolveOptions = beforeResolveResult.resolveOptions;

				let loaders;
				let resource;
				let loadersPrefix = "";
				const idx = request.lastIndexOf("!");
				if (idx >= 0) {
					let loadersRequest = request.slice(0, idx + 1);
					let i;
					for (
						i = 0;
						i < loadersRequest.length && loadersRequest[i] === "!";
						i++
					) {
						loadersPrefix += "!";
					}
					loadersRequest = loadersRequest
						.slice(i)
						.replace(/!+$/, "")
						.replace(/!!+/g, "!");
					loaders = loadersRequest === "" ? [] : loadersRequest.split("!");
					resource = request.slice(idx + 1);
				} else {
					loaders = [];
					resource = request;
				}

				const contextResolver = this.resolverFactory.get(
					"context",
					dependencies.length > 0
						? cachedSetProperty(
								resolveOptions || EMPTY_RESOLVE_OPTIONS,
								"dependencyType",
								dependencies[0].category
							)
						: resolveOptions
				);
				const loaderResolver = this.resolverFactory.get("loader");

				asyncLib.parallel(
					[
						callback => {
							const results = /** @type ResolveRequest[] */ ([]);
							/**
							 * @param {ResolveRequest} obj obj
							 * @returns {void}
							 */
							const yield_ = obj => {
								results.push(obj);
							};

							contextResolver.resolve(
								{},
								context,
								resource,
								{
									fileDependencies,
									missingDependencies,
									contextDependencies,
									yield: yield_
								},
								err => {
									if (err) return callback(err);
									callback(null, results);
								}
							);
						},
						callback => {
							asyncLib.map(
								loaders,
								(loader, callback) => {
									loaderResolver.resolve(
										{},
										context,
										loader,
										{
											fileDependencies,
											missingDependencies,
											contextDependencies
										},
										(err, result) => {
											if (err) return callback(err);
											callback(null, /** @type {string} */ (result));
										}
									);
								},
								callback
							);
						}
					],
					(err, result) => {
						if (err) {
							return callback(err, {
								fileDependencies,
								missingDependencies,
								contextDependencies
							});
						}
						let [contextResult, loaderResult] =
							/** @type {[ResolveRequest[], string[]]} */ (result);
						if (contextResult.length > 1) {
							const first = contextResult[0];
							contextResult = contextResult.filter(r => r.path);
							if (contextResult.length === 0) contextResult.push(first);
						}
						this.hooks.afterResolve.callAsync(
							{
								addon:
									loadersPrefix +
									loaderResult.join("!") +
									(loaderResult.length > 0 ? "!" : ""),
								resource:
									contextResult.length > 1
										? contextResult.map(r => r.path)
										: contextResult[0].path,
								resolveDependencies: this.resolveDependencies.bind(this),
								resourceQuery: contextResult[0].query,
								resourceFragment: contextResult[0].fragment,
								...beforeResolveResult
							},
							(err, result) => {
								if (err) {
									return callback(err, {
										fileDependencies,
										missingDependencies,
										contextDependencies
									});
								}

								// Ignored
								if (!result) {
									return callback(null, {
										fileDependencies,
										missingDependencies,
										contextDependencies
									});
								}

								return callback(null, {
									module: new ContextModule(result.resolveDependencies, result),
									fileDependencies,
									missingDependencies,
									contextDependencies
								});
							}
						);
					}
				);
			}
		);
	}
@param {ModuleFactoryCreateData} data data object
@param {ModuleFactoryCallback} callback callback
@returns {void}