static computeWasteWithGraph(results, graph, simulator, options) {
    options = Object.assign({label: ''}, options);
    const beforeLabel = `${this.meta.id}-${options.label}-before`;
    const afterLabel = `${this.meta.id}-${options.label}-after`;

    const simulationBeforeChanges = simulator.simulate(graph, {label: beforeLabel});

    const wastedBytesByUrl = options.providedWastedBytesByUrl || new Map();
    if (!options.providedWastedBytesByUrl) {
      for (const {url, wastedBytes} of results) {
        wastedBytesByUrl.set(url, (wastedBytesByUrl.get(url) || 0) + wastedBytes);
      }
    }

    // Update all the transfer sizes to reflect implementing our recommendations
    /** @type {Map<string, number>} */
    const originalTransferSizes = new Map();
    graph.traverse(node => {
      if (node.type !== 'network') return;
      const wastedBytes = wastedBytesByUrl.get(node.request.url);
      if (!wastedBytes) return;

      const original = node.request.transferSize;
      originalTransferSizes.set(node.request.requestId, original);

      node.request.transferSize = Math.max(original - wastedBytes, 0);
    });

    const simulationAfterChanges = simulator.simulate(graph, {label: afterLabel});

    // Restore the original transfer size after we've done our simulation
    graph.traverse(node => {
      if (node.type !== 'network') return;
      const originalTransferSize = originalTransferSizes.get(node.request.requestId);
      if (originalTransferSize === undefined) return;
      node.request.transferSize = originalTransferSize;
    });

    const savings = simulationBeforeChanges.timeInMs - simulationAfterChanges.timeInMs;

    return {
      // Round waste to nearest 10ms
      savings: Math.round(Math.max(savings, 0) / 10) * 10,
      simulationBeforeChanges,
      simulationAfterChanges,
    };
  }
Computes the estimated effect of all the byte savings on the provided graph.

@param {Array<LH.Audit.ByteEfficiencyItem>} results The array of byte savings results per resource
@param {LH.Gatherer.Simulation.GraphNode} graph
@param {LH.Gatherer.Simulation.Simulator} simulator
@param {{label?: string, providedWastedBytesByUrl?: Map<string, number>}=} options
@return {{savings: number, simulationBeforeChanges: LH.Gatherer.Simulation.Result, simulationAfterChanges: LH.Gatherer.Simulation.Result}}