cb = function(user) {
    if (self.currentUser_ &&
        !self.currentUser_['isAnonymous'] &&
        self.getConfig().autoUpgradeAnonymousUsers() &&
        !self.getAuth().currentUser) {
      return self.clearTempAuthState().then(function() {
        // Do not expose password Auth credential to signInSuccess callback.
        if (authResult['credential']['providerId'] == 'password') {
          authResult['credential'] = null;
        }
        return authResult;
      });
    } else if (user) {
      // TODO: optimize and fail directly as this will fail in most cases
      // with error credential already in use.
      // There are cases where this is required. For example, when email
      // mismatch occurs and the user continues with the new account.
      return (
          /**
           * @type {!firebase.Promise<
           *     !firebaseui.auth.widget.Config.AuthResult>}
           */ (
          self.clearTempAuthState().then(function() {
            return user.linkWithCredential(
                authResult['credential']);
          }).then(function(userCredential) {
            authResult['user'] = userCredential['user'];
            authResult['credential'] = userCredential['credential'];
            authResult['operationType'] = userCredential['operationType'];
            authResult['additionalUserInfo'] =
                userCredential['additionalUserInfo'];
            return authResult;
          }, function(error) {
            // Rethrow email already in use error so it can trigger the account
            // linking flow.
            if (error &&
                error['code'] == 'auth/email-already-in-use' &&
                error['email'] && error['credential']) {
              throw error;
            }
            // For all other errors, run onUpgrade check.
            return self.onUpgradeError(error, authResult['credential']);
          })));
    } else {
      // Finishes sign in with the supplied credential on the developer provided
      // Auth instance. On completion, this will redirect to signInSuccessUrl or
      // trigger the signInSuccessWithAuthResult callback.
      if (!authResult['user']) {
        throw new Error(firebaseui.auth.AuthUI.INCOMPATIBLE_DEPENDENCY_ERROR);
      }
      return self.clearTempAuthState().then(function() {
        // updateCurrentUser is more efficient and less error prone than
        // signInWithCredential.
        // The former can resolve the operation without any network request
        // whereas the latter will send 2 requests.
        // In addition, updateCurrentUser has lower risk of failure in the
        // following cases:
        // 1. No network connection: operation can execute without any network
        // call in most cases.
        // 2. Will not run into expired OAuth credential errors unlike
        // signInWithCredential. This may happen if the user waits too long
        // before completing sign-in in the email mismatch flow.
        // 3. Ability to copy a user for all providers. Some OAuth providers
        // cannot be used headlessly or their credentials are one-time only.
        return self.getExternalAuth().updateCurrentUser(authResult['user']);
      }).then(function() {
        // Update user reference.
        authResult['user'] = self.getExternalAuth().currentUser;
        // Update operation type to signIn. This will not run for anonymous
        // upgrade flows.
        authResult['operationType'] = 'signIn';
        // Clear password credential if available
        if (authResult['credential'] &&
            authResult['credential']['providerId'] &&
            authResult['credential']['providerId'] == 'password') {
          authResult['credential'] = null;
        }
        // AdditionalUserInfo should remain the same as isNewUser field
        // should be the one returned in the first sign in attempt.
        return authResult;
      });
    }
  }
Finishes FirebaseUI login with the given 3rd party credentials.
@param {!firebaseui.auth.widget.Config.AuthResult} authResult The Auth
    result.
@return {!firebase.Promise<!firebaseui.auth.widget.Config.AuthResult>}