Merge changes from topic "async-foreach-util"

* changes:
  Convert AsyncForeachBehavior to util function
  Move async-foreach-behavior to util to preserve history
diff --git a/polygerrit-ui/app/behaviors/async-foreach-behavior/async-foreach-behavior.js b/polygerrit-ui/app/behaviors/async-foreach-behavior/async-foreach-behavior.js
deleted file mode 100644
index 1d384bc..0000000
--- a/polygerrit-ui/app/behaviors/async-foreach-behavior/async-foreach-behavior.js
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * @license
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/** @polymerBehavior AsyncForeachBehavior */
-export const AsyncForeachBehavior = {
-  /**
-   * @template T
-   * @param {!Array<T>} array
-   * @param {!Function} fn An iteratee function to be passed each element of
-   *     the array in order. Must return a promise, and the following
-   *     iteration will not begin until resolution of the promise returned by
-   *     the previous iteration.
-   *
-   *     An optional second argument to fn is a callback that will halt the
-   *     loop if called.
-   * @return {!Promise<undefined>}
-   */
-  asyncForeach(array, fn) {
-    if (!array.length) { return Promise.resolve(); }
-    let stop = false;
-    const stopCallback = () => { stop = true; };
-    return fn(array[0], stopCallback).then(exit => {
-      if (stop) { return Promise.resolve(); }
-      return this.asyncForeach(array.slice(1), fn);
-    });
-  },
-};
-
-// TODO(dmfilippov) Remove the following lines with assignments
-// Plugins can use the behavior because it was accessible with
-// the global Gerrit... variable. To avoid breaking changes in plugins
-// temporary assign global variables.
-window.Gerrit = window.Gerrit || {};
-window.Gerrit.AsyncForeachBehavior = AsyncForeachBehavior;
diff --git a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.js b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.js
index 44700e9..df6490d 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.js
+++ b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.js
@@ -33,7 +33,7 @@
 import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin.js';
 import {PolymerElement} from '@polymer/polymer/polymer-element.js';
 import {htmlTemplate} from './gr-file-list_html.js';
-import {AsyncForeachBehavior} from '../../../behaviors/async-foreach-behavior/async-foreach-behavior.js';
+import {asyncForeach} from '../../../utils/async-util.js';
 import {DomUtilBehavior} from '../../../behaviors/dom-util-behavior/dom-util-behavior.js';
 import {PatchSetBehavior} from '../../../behaviors/gr-patch-set-behavior/gr-patch-set-behavior.js';
 import {PathListBehavior} from '../../../behaviors/gr-path-list-behavior/gr-path-list-behavior.js';
@@ -91,7 +91,6 @@
  * @extends PolymerElement
  */
 class GrFileList extends mixinBehaviors( [
-  AsyncForeachBehavior,
   DomUtilBehavior,
   KeyboardShortcutBehavior,
   PatchSetBehavior,
@@ -1292,7 +1291,7 @@
         detail: {resolve},
         composed: true, bubbles: true,
       }));
-    })).then(() => this.asyncForeach(files, (file, cancel) => {
+    })).then(() => asyncForeach(files, (file, cancel) => {
       const path = file.path;
       this._cancelForEachDiff = cancel;
 
diff --git a/polygerrit-ui/app/utils/async-util.js b/polygerrit-ui/app/utils/async-util.js
new file mode 100644
index 0000000..14d0288
--- /dev/null
+++ b/polygerrit-ui/app/utils/async-util.js
@@ -0,0 +1,38 @@
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @template T
+ * @param {!Array<T>} array
+ * @param {!Function} fn An iteratee function to be passed each element of
+ *     the array in order. Must return a promise, and the following
+ *     iteration will not begin until resolution of the promise returned by
+ *     the previous iteration.
+ *
+ *     An optional second argument to fn is a callback that will halt the
+ *     loop if called.
+ * @return {!Promise<undefined>}
+ */
+export function asyncForeach(array, fn) {
+  if (!array.length) { return Promise.resolve(); }
+  let stop = false;
+  const stopCallback = () => { stop = true; };
+  return fn(array[0], stopCallback).then(exit => {
+    if (stop) { return Promise.resolve(); }
+    return asyncForeach(array.slice(1), fn);
+  });
+}
diff --git a/polygerrit-ui/app/behaviors/async-foreach-behavior/async-foreach-behavior_test.js b/polygerrit-ui/app/utils/async-util_test.js
similarity index 81%
rename from polygerrit-ui/app/behaviors/async-foreach-behavior/async-foreach-behavior_test.js
rename to polygerrit-ui/app/utils/async-util_test.js
index 0a44884..df29e97 100644
--- a/polygerrit-ui/app/behaviors/async-foreach-behavior/async-foreach-behavior_test.js
+++ b/polygerrit-ui/app/utils/async-util_test.js
@@ -15,12 +15,13 @@
  * limitations under the License.
  */
 
-import '../../test/common-test-setup-karma.js';
-import {AsyncForeachBehavior} from './async-foreach-behavior.js';
-suite('async-foreach-behavior tests', () => {
+import '../test/common-test-setup-karma.js';
+import {asyncForeach} from './async-util.js';
+
+suite('async-util tests', () => {
   test('loops over each item', () => {
     const fn = sinon.stub().returns(Promise.resolve());
-    return AsyncForeachBehavior.asyncForeach([1, 2, 3], fn)
+    return asyncForeach([1, 2, 3], fn)
         .then(() => {
           assert.isTrue(fn.calledThrice);
           assert.equal(fn.getCall(0).args[0], 1);
@@ -36,7 +37,7 @@
       stop();
       return Promise.resolve();
     };
-    return AsyncForeachBehavior.asyncForeach([1, 2, 3], fn)
+    return asyncForeach([1, 2, 3], fn)
         .then(() => {
           assert.isTrue(stub.calledOnce);
           assert.equal(stub.lastCall.args[0], 1);