removeAsset(asset) {
    if (!this.idIndex[asset.id]) {
      throw new Error(`AssetGraph.removeAsset: ${asset} not in graph`);
    }
    if (asset._outgoingRelations) {
      const outgoingRelations = [...asset._outgoingRelations];
      // Remove the outgoing relations as to not trigger the
      // "<relation> will be detached..." warning in the recursive
      // removeAsset calls:
      asset._outgoingRelations = undefined;

      for (const outgoingRelation of outgoingRelations) {
        if (
          outgoingRelation.to.isAsset &&
          outgoingRelation.to.isInline &&
          outgoingRelation.to !== outgoingRelation.from
        ) {
          // Remove inline asset
          this.removeAsset(outgoingRelation.to);
        }
      }
      // Put back the outgoing relations so that the relations are still
      // in a resolved state, even though the asset is no longer in the
      // graph. This is debatable since we don't really want to support
      // assets living outside of the context of an AssetGraph instance,
      // but not doing it makes a test fail here:
      //   https://github.com/assetgraph/assetgraph/blob/348b8740941effc93106abe84f9225cccf10470d/test/assets/Asset.js#L691-L695
      // ... so let's consider whether to nuke that test at some point.
      asset._outgoingRelations = outgoingRelations;
    }
    let stillAttachedIncomingRelations = false;
    for (const incomingRelation of asset.incomingRelations) {
      if (
        incomingRelation.from !== incomingRelation.to &&
        incomingRelation.hrefType !== 'inline'
      ) {
        this.warn(
          new Error(
            `${incomingRelation.toString()} will be detached as a result of removing ${
              asset.urlOrDescription
            } from the graph`
          )
        );
        try {
          incomingRelation.detach();
        } catch (e) {
          incomingRelation.remove();
          stillAttachedIncomingRelations = true;
        }
      } else {
        incomingRelation.remove();
      }
    }
    if (stillAttachedIncomingRelations) {
      this.warn(
        new Error(
          `Leaving ${asset.urlOrDescription} unloaded in the graph, some incoming relations could not be detached`
        )
      );
      asset.unload();
    } else {
      if (!this._assets.delete(asset)) {
        throw new Error(`removeAsset: ${asset} not in graph`);
      }
      this.idIndex[asset.id] = undefined;
      const url = asset.url;
      if (url) {
        if (this._urlIndex[url]) {
          delete this._urlIndex[url];
        } else {
          throw new Error(`Internal error: ${url} not in _urlIndex`);
        }
      }
      asset.assetGraph = undefined;
      this.emit('removeAsset', asset);
    }
    return this;
  }
Remove an asset from the graph. Also removes the incoming and
outgoing relations of the asset.

@param {Asset} asset The asset to remove.
@return {AssetGraph} The AssetGraph instance (chaining-friendly).