static fillInDrmInfoDefaults_(drmInfo, servers, advancedConfigs,
      keySystemsMapping) {
    const originalKeySystem = drmInfo.keySystem;

    if (!originalKeySystem) {
      // This is a placeholder from the manifest parser for an unrecognized key
      // system.  Skip this entry, to avoid logging nonsensical errors.
      return;
    }

    // The order of preference for drmInfo:
    // 1. Clear Key config, used for debugging, should override everything else.
    //    (The application can still specify a clearkey license server.)
    // 2. Application-configured servers, if present, override
    //    anything from the manifest.
    // 3. Manifest-provided license servers are only used if nothing else is
    //    specified.
    // This is important because it allows the application a clear way to
    // indicate which DRM systems should be ignored on platforms with multiple
    // DRM systems.
    // Alternatively, use config.preferredKeySystems to specify the preferred
    // key system.

    if (originalKeySystem == 'org.w3.clearkey' && drmInfo.licenseServerUri) {
      // Preference 1: Clear Key with pre-configured keys will have a data URI
      // assigned as its license server.  Don't change anything.
      return;
    } else if (servers.size && servers.get(originalKeySystem)) {
      // Preference 2: If a license server for this keySystem is configured at
      // the application level, override whatever was in the manifest.
      const server = servers.get(originalKeySystem);

      drmInfo.licenseServerUri = server;
    } else {
      // Preference 3: Keep whatever we had in drmInfo.licenseServerUri, which
      // comes from the manifest.
    }

    if (!drmInfo.keyIds) {
      drmInfo.keyIds = new Set();
    }

    const advancedConfig = advancedConfigs.get(originalKeySystem);

    if (advancedConfig) {
      if (!drmInfo.distinctiveIdentifierRequired) {
        drmInfo.distinctiveIdentifierRequired =
            advancedConfig.distinctiveIdentifierRequired;
      }

      if (!drmInfo.persistentStateRequired) {
        drmInfo.persistentStateRequired =
            advancedConfig.persistentStateRequired;
      }

      // robustness will be filled in with defaults, if needed, in
      // expandRobustness

      if (!drmInfo.serverCertificate) {
        drmInfo.serverCertificate = advancedConfig.serverCertificate;
      }

      if (advancedConfig.sessionType) {
        drmInfo.sessionType = advancedConfig.sessionType;
      }

      if (!drmInfo.serverCertificateUri) {
        drmInfo.serverCertificateUri = advancedConfig.serverCertificateUri;
      }
    }

    if (keySystemsMapping[originalKeySystem]) {
      drmInfo.keySystem = keySystemsMapping[originalKeySystem];
    }

    // Chromecast has a variant of PlayReady that uses a different key
    // system ID.  Since manifest parsers convert the standard PlayReady
    // UUID to the standard PlayReady key system ID, here we will switch
    // to the Chromecast version if we are running on that platform.
    // Note that this must come after fillInDrmInfoDefaults_, since the
    // player config uses the standard PlayReady ID for license server
    // configuration.
    if (window.cast && window.cast.__platform__) {
      if (originalKeySystem == 'com.microsoft.playready') {
        drmInfo.keySystem = 'com.chromecast.playready';
      }
    }
  }
Use |servers| and |advancedConfigs| to fill in missing values in drmInfo
that the parser left blank. Before working with any drmInfo, it should be
passed through here as it is uncommon for drmInfo to be complete when
fetched from a manifest because most manifest formats do not have the
required information. Also applies the key systems mapping.

@param {shaka.extern.DrmInfo} drmInfo
@param {!Map<string, string>} servers
@param {!Map<string,
              shaka.extern.AdvancedDrmConfiguration>} advancedConfigs
@param {!Object<string, string>} keySystemsMapping
@private