handler = (chunks, chunkGroups) => {
				const chunkGraph = compilation.chunkGraph;
				const queue = new Set();
				const availableModulesMap = new WeakMap();

				let nextModuleMask = ONE_BIGINT;
				const maskByModule = new WeakMap();
				/** @type {Module[]} */
				const ordinalModules = [];

				/**
				 * Gets or creates a unique mask for a module
				 * @param {Module} mod the module to get the mask for
				 * @returns {bigint} the module mask to uniquely identify the module
				 */
				const getOrCreateModuleMask = mod => {
					let id = maskByModule.get(mod);
					if (id === undefined) {
						id = nextModuleMask;
						ordinalModules.push(mod);
						maskByModule.set(mod, id);
						nextModuleMask <<= ONE_BIGINT;
					}
					return id;
				};

				// Initialize masks by chunk and by chunk group for quicker comparisons
				const chunkMasks = new WeakMap();
				for (const chunk of chunks) {
					let mask = ZERO_BIGINT;
					for (const m of chunkGraph.getChunkModulesIterable(chunk)) {
						const id = getOrCreateModuleMask(m);
						mask |= id;
					}
					chunkMasks.set(chunk, mask);
				}

				const chunkGroupMasks = new WeakMap();
				for (const chunkGroup of chunkGroups) {
					let mask = ZERO_BIGINT;
					for (const chunk of chunkGroup.chunks) {
						const chunkMask = chunkMasks.get(chunk);
						if (chunkMask !== undefined) {
							mask |= chunkMask;
						}
					}
					chunkGroupMasks.set(chunkGroup, mask);
				}

				for (const chunkGroup of compilation.entrypoints.values()) {
					// initialize available modules for chunks without parents
					availableModulesMap.set(chunkGroup, ZERO_BIGINT);
					for (const child of chunkGroup.childrenIterable) {
						queue.add(child);
					}
				}
				for (const chunkGroup of compilation.asyncEntrypoints) {
					// initialize available modules for chunks without parents
					availableModulesMap.set(chunkGroup, ZERO_BIGINT);
					for (const child of chunkGroup.childrenIterable) {
						queue.add(child);
					}
				}

				for (const chunkGroup of queue) {
					let availableModulesMask = availableModulesMap.get(chunkGroup);
					let changed = false;
					for (const parent of chunkGroup.parentsIterable) {
						const availableModulesInParent = availableModulesMap.get(parent);
						if (availableModulesInParent !== undefined) {
							const parentMask =
								availableModulesInParent | chunkGroupMasks.get(parent);
							// If we know the available modules in parent: process these
							if (availableModulesMask === undefined) {
								// if we have not own info yet: create new entry
								availableModulesMask = parentMask;
								changed = true;
							} else {
								const newMask = availableModulesMask & parentMask;
								if (newMask !== availableModulesMask) {
									changed = true;
									availableModulesMask = newMask;
								}
							}
						}
					}

					if (changed) {
						availableModulesMap.set(chunkGroup, availableModulesMask);
						// if something changed: enqueue our children
						for (const child of chunkGroup.childrenIterable) {
							// Push the child to the end of the queue
							queue.delete(child);
							queue.add(child);
						}
					}
				}

				// now we have available modules for every chunk
				for (const chunk of chunks) {
					const chunkMask = chunkMasks.get(chunk);
					if (chunkMask === undefined) continue; // No info about this chunk

					const availableModulesSets = Array.from(
						chunk.groupsIterable,
						chunkGroup => availableModulesMap.get(chunkGroup)
					);
					if (availableModulesSets.includes(undefined)) continue; // No info about this chunk group

					const availableModulesMask = intersectMasks(availableModulesSets);
					const toRemoveMask = chunkMask & availableModulesMask;
					if (toRemoveMask !== ZERO_BIGINT) {
						for (const module of getModulesFromMask(
							toRemoveMask,
							ordinalModules
						)) {
							chunkGraph.disconnectChunkAndModule(chunk, module);
						}
					}
				}
			}
@param {Iterable<Chunk>} chunks the chunks
@param {ChunkGroup[]} chunkGroups the chunk groups