Merge "SafeProtoConverterTest: test proto defaults"
diff --git a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.ts b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.ts
index b2b045a..c76e928 100644
--- a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.ts
+++ b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.ts
@@ -123,7 +123,7 @@
 import {Key, Modifier, whenVisible} from '../../../utils/dom-util';
 import {GrThreadList} from '../gr-thread-list/gr-thread-list';
 import {userModelToken} from '../../../models/user/user-model';
-import {accountsModelToken} from '../../../models/accounts-model/accounts-model';
+import {accountsModelToken} from '../../../models/accounts/accounts-model';
 import {pluginLoaderToken} from '../../shared/gr-js-api-interface/gr-plugin-loader';
 import {modalStyles} from '../../../styles/gr-modal-styles';
 import {ironAnnouncerRequestAvailability} from '../../polymer-util';
diff --git a/polygerrit-ui/app/elements/settings/gr-email-editor/gr-email-editor.ts b/polygerrit-ui/app/elements/settings/gr-email-editor/gr-email-editor.ts
index 634b17a..4497cf81 100644
--- a/polygerrit-ui/app/elements/settings/gr-email-editor/gr-email-editor.ts
+++ b/polygerrit-ui/app/elements/settings/gr-email-editor/gr-email-editor.ts
@@ -13,7 +13,7 @@
 import {grFormStyles} from '../../../styles/gr-form-styles';
 import {ValueChangedEvent} from '../../../types/events';
 import {fire} from '../../../utils/event-util';
-import {notDeepEqual} from '../../../utils/deep-util';
+import {deepClone} from '../../../utils/deep-util';
 
 @customElement('gr-email-editor')
 export class GrEmailEditor extends LitElement {
@@ -111,8 +111,9 @@
 
   loadData() {
     return this.restApiService.getAccountEmails().then(emails => {
-      this.originalEmails = emails ?? [];
-      this.emails = emails ? [...emails] : [];
+      if (!emails) return;
+      this.originalEmails = deepClone(emails);
+      this.emails = emails;
     });
   }
 
@@ -146,7 +147,12 @@
     const email = this.emails[index];
     // Don't add project to emailsToRemove if it wasn't in
     // originalEmails.
-    if (this.originalEmails.includes(email)) this.emailsToRemove.push(email);
+    // We have to use JSON.stringify as we cloned the array
+    // so the reference is not the same.
+    const emails = this.originalEmails.some(
+      x => JSON.stringify(email) === JSON.stringify(x)
+    );
+    if (emails) this.emailsToRemove.push(email);
     this.emails.splice(index, 1);
     this.requestUpdate();
     this.setHasUnsavedChanges();
@@ -172,7 +178,8 @@
         this.newPreferred = preferred;
         this.setHasUnsavedChanges();
       } else if (this.emails[i].preferred) {
-        this.emails[i].preferred = false;
+        delete this.emails[i].preferred;
+        this.setHasUnsavedChanges();
         this.requestUpdate();
       }
     }
@@ -184,7 +191,7 @@
 
   private setHasUnsavedChanges() {
     const hasUnsavedChanges =
-      notDeepEqual(this.originalEmails, this.emails) ||
+      JSON.stringify(this.originalEmails) !== JSON.stringify(this.emails) ||
       this.emailsToRemove.length > 0;
     fire(this, 'has-unsaved-changes-changed', {value: hasUnsavedChanges});
   }
diff --git a/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label.ts b/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label.ts
index d77bec9..691eec4 100644
--- a/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label.ts
+++ b/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label.ts
@@ -21,7 +21,7 @@
 import {getRemovedByIconClickReason} from '../../../utils/attention-set-util';
 import {ifDefined} from 'lit/directives/if-defined.js';
 import {createSearchUrl} from '../../../models/views/search';
-import {accountsModelToken} from '../../../models/accounts-model/accounts-model';
+import {accountsModelToken} from '../../../models/accounts/accounts-model';
 import {resolve} from '../../../models/dependency';
 import {configModelToken} from '../../../models/config/config-model';
 import {userModelToken} from '../../../models/user/user-model';
diff --git a/polygerrit-ui/app/elements/shared/gr-avatar/gr-avatar-stack.ts b/polygerrit-ui/app/elements/shared/gr-avatar/gr-avatar-stack.ts
index 863ee90..b445f75 100644
--- a/polygerrit-ui/app/elements/shared/gr-avatar/gr-avatar-stack.ts
+++ b/polygerrit-ui/app/elements/shared/gr-avatar/gr-avatar-stack.ts
@@ -17,7 +17,7 @@
 import {configModelToken} from '../../../models/config/config-model';
 import {subscribe} from '../../lit/subscription-controller';
 import {getDisplayName} from '../../../utils/display-name-util';
-import {accountsModelToken} from '../../../models/accounts-model/accounts-model';
+import {accountsModelToken} from '../../../models/accounts/accounts-model';
 import {isDefined} from '../../../types/types';
 import {when} from 'lit/directives/when.js';
 
diff --git a/polygerrit-ui/app/models/accounts-model/accounts-model.ts b/polygerrit-ui/app/models/accounts/accounts-model.ts
similarity index 100%
rename from polygerrit-ui/app/models/accounts-model/accounts-model.ts
rename to polygerrit-ui/app/models/accounts/accounts-model.ts
diff --git a/polygerrit-ui/app/models/accounts-model/accounts-model_test.ts b/polygerrit-ui/app/models/accounts/accounts-model_test.ts
similarity index 100%
rename from polygerrit-ui/app/models/accounts-model/accounts-model_test.ts
rename to polygerrit-ui/app/models/accounts/accounts-model_test.ts
diff --git a/polygerrit-ui/app/models/comments/comments-model.ts b/polygerrit-ui/app/models/comments/comments-model.ts
index f9a8401..ed492c1 100644
--- a/polygerrit-ui/app/models/comments/comments-model.ts
+++ b/polygerrit-ui/app/models/comments/comments-model.ts
@@ -56,7 +56,7 @@
 import {Deduping} from '../../api/reporting';
 import {extractMentionedUsers, getUserId} from '../../utils/account-util';
 import {SpecialFilePath} from '../../constants/constants';
-import {AccountsModel} from '../accounts-model/accounts-model';
+import {AccountsModel} from '../accounts/accounts-model';
 import {
   distinctUntilChanged,
   map,
diff --git a/polygerrit-ui/app/models/comments/comments-model_test.ts b/polygerrit-ui/app/models/comments/comments-model_test.ts
index 0d3df42..b3dbc08 100644
--- a/polygerrit-ui/app/models/comments/comments-model_test.ts
+++ b/polygerrit-ui/app/models/comments/comments-model_test.ts
@@ -28,7 +28,7 @@
 import {changeModelToken} from '../change/change-model';
 import {assert} from '@open-wc/testing';
 import {testResolver} from '../../test/common-test-setup';
-import {accountsModelToken} from '../accounts-model/accounts-model';
+import {accountsModelToken} from '../accounts/accounts-model';
 import {ChangeComments} from '../../elements/diff/gr-comment-api/gr-comment-api';
 import {changeViewModelToken} from '../views/change';
 import {navigationToken} from '../../elements/core/gr-navigation/gr-navigation';
diff --git a/polygerrit-ui/app/services/app-context-init.ts b/polygerrit-ui/app/services/app-context-init.ts
index 40517ac..8536492 100644
--- a/polygerrit-ui/app/services/app-context-init.ts
+++ b/polygerrit-ui/app/services/app-context-init.ts
@@ -34,7 +34,7 @@
 import {
   AccountsModel,
   accountsModelToken,
-} from '../models/accounts-model/accounts-model';
+} from '../models/accounts/accounts-model';
 import {
   DashboardViewModel,
   dashboardViewModelToken,