getProvidersForTenant(tenantId, email = undefined) {
    const uiConfigs = this.config_.get('tenants');
    if (!uiConfigs) {
      throw new Error('Invalid tenant configuration!');
    }
    const providers = [];
    const tenantConfig =
        uiConfigs[tenantId] ||
        uiConfigs[UiHandlerConfig.ConfigKeys.DEFAULT_CONFIG_KEY];
    if (!tenantConfig) {
      log.error(`Invalid tenant configuration: `+
                `${tenantId} is not configured!`);
      return providers;
    }
    const signInOptions = tenantConfig['signInOptions'];
    if (!signInOptions) {
      throw new Error(
          'Invalid tenant configuration: signInOptions are invalid!');
    }
    signInOptions.forEach((option) => {
      if (typeof option === 'string') {
        // No hd configured, treat like a match for any email.
        providers.push(option);
      } else if (typeof option['provider'] === 'string') {
        const hd = option['hd'];
        // If hd is configured, match the email with the hd.
        if (hd && email) {
          const regex = hd instanceof RegExp ?
              hd : new RegExp('@' + hd.replace('.', '\\.') + '$');
          if (regex.test(email)) {
            providers.push(option['provider']);
          }
        } else {
           // No hd configured, treat like a match for any email.
          providers.push(option['provider']);
        }
      } else {
        log.error(
            `Invalid tenant configuration: signInOption ` +
            `${JSON.stringify(option)} is invalid!`);
      }
    });
    return providers;
  }
Returns the providers enabled for the given tenant. If email is provided,
only returns the providers that match with the given email. Note that if
email is passed but no hd is available, the associated provider is
still returned.
@param {string} tenantId The tenant ID or project-level config key.
@param {?string=} email The optional email used to match providers.
@return {!Array<string>} The list of enabled provider IDs.