/**
 * @license
 * Copyright (C) 2016 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.
 */
import '../../admin/gr-create-change-dialog/gr-create-change-dialog.js';
import '../../shared/gr-button/gr-button.js';
import '../../shared/gr-dialog/gr-dialog.js';
import '../../shared/gr-dropdown/gr-dropdown.js';
import '../../shared/gr-icons/gr-icons.js';
import '../../shared/gr-js-api-interface/gr-js-api-interface.js';
import '../../shared/gr-overlay/gr-overlay.js';
import '../../shared/gr-rest-api-interface/gr-rest-api-interface.js';
import '../gr-confirm-abandon-dialog/gr-confirm-abandon-dialog.js';
import '../gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog.js';
import '../gr-confirm-cherrypick-conflict-dialog/gr-confirm-cherrypick-conflict-dialog.js';
import '../gr-confirm-move-dialog/gr-confirm-move-dialog.js';
import '../gr-confirm-rebase-dialog/gr-confirm-rebase-dialog.js';
import '../gr-confirm-revert-dialog/gr-confirm-revert-dialog.js';
import '../gr-confirm-revert-submission-dialog/gr-confirm-revert-submission-dialog.js';
import '../gr-confirm-submit-dialog/gr-confirm-submit-dialog.js';
import '../../../styles/shared-styles.js';
import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners.js';
import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin.js';
import {PolymerElement} from '@polymer/polymer/polymer-element.js';
import {htmlTemplate} from './gr-change-actions_html.js';
import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';
import {pluginLoader} from '../../shared/gr-js-api-interface/gr-plugin-loader.js';
import {appContext} from '../../../services/app-context.js';
import {
  fetchChangeUpdates,
  patchNumEquals,
} from '../../../utils/patch-set-util.js';
import {
  changeIsOpen,
  ListChangesOption,
  listChangesOptionsToHex,
} from '../../../utils/change-util.js';
import {NotifyType} from '../../../constants/constants.js';
import {TargetElement, EventType} from '../../plugins/gr-plugin-types.js';

const ERR_BRANCH_EMPTY = 'The destination branch can’t be empty.';
const ERR_COMMIT_EMPTY = 'The commit message can’t be empty.';
const ERR_REVISION_ACTIONS = 'Couldn’t load revision actions.';
/**
 * @enum {string}
 */
const LabelStatus = {
  /**
   * This label provides what is necessary for submission.
   */
  OK: 'OK',
  /**
   * This label prevents the change from being submitted.
   */
  REJECT: 'REJECT',
  /**
   * The label may be set, but it's neither necessary for submission
   * nor does it block submission if set.
   */
  MAY: 'MAY',
  /**
   * The label is required for submission, but has not been satisfied.
   */
  NEED: 'NEED',
  /**
   * The label is required for submission, but is impossible to complete.
   * The likely cause is access has not been granted correctly by the
   * project owner or site administrator.
   */
  IMPOSSIBLE: 'IMPOSSIBLE',
  OPTIONAL: 'OPTIONAL',
};

const ChangeActions = {
  ABANDON: 'abandon',
  DELETE: '/',
  DELETE_EDIT: 'deleteEdit',
  EDIT: 'edit',
  FOLLOW_UP: 'followup',
  IGNORE: 'ignore',
  MOVE: 'move',
  PRIVATE: 'private',
  PRIVATE_DELETE: 'private.delete',
  PUBLISH_EDIT: 'publishEdit',
  REBASE: 'rebase',
  REBASE_EDIT: 'rebaseEdit',
  READY: 'ready',
  RESTORE: 'restore',
  REVERT: 'revert',
  REVERT_SUBMISSION: 'revert_submission',
  REVIEWED: 'reviewed',
  STOP_EDIT: 'stopEdit',
  SUBMIT: 'submit',
  UNIGNORE: 'unignore',
  UNREVIEWED: 'unreviewed',
  WIP: 'wip',
};

const RevisionActions = {
  CHERRYPICK: 'cherrypick',
  REBASE: 'rebase',
  SUBMIT: 'submit',
  DOWNLOAD: 'download',
};

const ActionLoadingLabels = {
  abandon: 'Abandoning...',
  cherrypick: 'Cherry-picking...',
  delete: 'Deleting...',
  move: 'Moving..',
  rebase: 'Rebasing...',
  restore: 'Restoring...',
  revert: 'Reverting...',
  revert_submission: 'Reverting Submission...',
  submit: 'Submitting...',
};

const ActionType = {
  CHANGE: 'change',
  REVISION: 'revision',
};

const ADDITIONAL_ACTION_KEY_PREFIX = '__additionalAction_';

const QUICK_APPROVE_ACTION = {
  __key: 'review',
  __type: 'change',
  enabled: true,
  key: 'review',
  label: 'Quick approve',
  method: 'POST',
};

const ActionPriority = {
  CHANGE: 2,
  DEFAULT: 0,
  PRIMARY: 3,
  REVIEW: -3,
  REVISION: 1,
};

const DOWNLOAD_ACTION = {
  enabled: true,
  label: 'Download patch',
  title: 'Open download dialog',
  __key: 'download',
  __primary: false,
  __type: 'revision',
};

const REBASE_EDIT = {
  enabled: true,
  label: 'Rebase edit',
  title: 'Rebase change edit',
  __key: 'rebaseEdit',
  __primary: false,
  __type: 'change',
  method: 'POST',
};

const PUBLISH_EDIT = {
  enabled: true,
  label: 'Publish edit',
  title: 'Publish change edit',
  __key: 'publishEdit',
  __primary: false,
  __type: 'change',
  method: 'POST',
};

const DELETE_EDIT = {
  enabled: true,
  label: 'Delete edit',
  title: 'Delete change edit',
  __key: 'deleteEdit',
  __primary: false,
  __type: 'change',
  method: 'DELETE',
};

const EDIT = {
  enabled: true,
  label: 'Edit',
  title: 'Edit this change',
  __key: 'edit',
  __primary: false,
  __type: 'change',
};

const STOP_EDIT = {
  enabled: true,
  label: 'Stop editing',
  title: 'Stop editing this change',
  __key: 'stopEdit',
  __primary: false,
  __type: 'change',
};

// Set of keys that have icons. As more icons are added to gr-icons.html, this
// set should be expanded.
const ACTIONS_WITH_ICONS = new Set([
  ChangeActions.ABANDON,
  ChangeActions.DELETE_EDIT,
  ChangeActions.EDIT,
  ChangeActions.PUBLISH_EDIT,
  ChangeActions.READY,
  ChangeActions.REBASE_EDIT,
  ChangeActions.RESTORE,
  ChangeActions.REVERT,
  ChangeActions.REVERT_SUBMISSION,
  ChangeActions.STOP_EDIT,
  QUICK_APPROVE_ACTION.key,
  RevisionActions.REBASE,
  RevisionActions.SUBMIT,
]);

const AWAIT_CHANGE_ATTEMPTS = 5;
const AWAIT_CHANGE_TIMEOUT_MS = 1000;

const REVERT_TYPES = {
  REVERT_SINGLE_CHANGE: 1,
  REVERT_SUBMISSION: 2,
};

/* Revert submission is skipped as the normal revert dialog will now show
the user a choice between reverting single change or an entire submission.
Hence, a second button is not needed.
*/
const SKIP_ACTION_KEYS = [ChangeActions.REVERT_SUBMISSION];

const SKIP_ACTION_KEYS_ATTENTION_SET = [
  ChangeActions.REVIEWED,
  ChangeActions.UNREVIEWED,
];

/**
 * @extends PolymerElement
 */
class GrChangeActions extends GestureEventListeners(
    LegacyElementMixin(PolymerElement)) {
  static get template() { return htmlTemplate; }

  static get is() { return 'gr-change-actions'; }
  /**
   * Fired when the change should be reloaded.
   *
   * @event reload
   */

  /**
   * Fired when an action is tapped.
   *
   * @event custom-tap - naming pattern: <action key>-tap
   */

  /**
   * Fires to show an alert when a send is attempted on the non-latest patch.
   *
   * @event show-alert
   */

  /**
   * Fires when a change action fails.
   *
   * @event show-error
   */

  constructor() {
    super();
    this.ActionType = ActionType;
    this.ChangeActions = ChangeActions;
    this.RevisionActions = RevisionActions;
    this.reporting = appContext.reportingService;
  }

  static get properties() {
    return {
    /**
     * @type {{
     *    _number: number,
     *    branch: string,
     *    id: string,
     *    project: string,
     *    subject: string,
     *  }}
     */
      change: Object,
      actions: {
        type: Object,
        value() { return {}; },
      },
      primaryActionKeys: {
        type: Array,
        value() {
          return [
            ChangeActions.READY,
            RevisionActions.SUBMIT,
          ];
        },
      },
      disableEdit: {
        type: Boolean,
        value: false,
      },
      _hasKnownChainState: {
        type: Boolean,
        value: false,
      },
      _hideQuickApproveAction: {
        type: Boolean,
        value: false,
      },
      changeNum: String,
      changeStatus: String,
      commitNum: String,
      hasParent: {
        type: Boolean,
        observer: '_computeChainState',
      },
      latestPatchNum: String,
      commitMessage: {
        type: String,
        value: '',
      },
      /** @type {?} */
      revisionActions: {
        type: Object,
        notify: true,
        value() { return {}; },
      },
      // If property binds directly to [[revisionActions.submit]] it is not
      // updated when revisionActions doesn't contain submit action.
      /** @type {?} */
      _revisionSubmitAction: {
        type: Object,
        computed: '_getSubmitAction(revisionActions)',
      },
      // If property binds directly to [[revisionActions.rebase]] it is not
      // updated when revisionActions doesn't contain rebase action.
      /** @type {?} */
      _revisionRebaseAction: {
        type: Object,
        computed: '_getRebaseAction(revisionActions)',
      },
      privateByDefault: String,

      _loading: {
        type: Boolean,
        value: true,
      },
      _actionLoadingMessage: {
        type: String,
        value: '',
      },
      _allActionValues: {
        type: Array,
        computed: '_computeAllActions(actions.*, revisionActions.*,' +
          'primaryActionKeys.*, _additionalActions.*, change, ' +
          '_config, _actionPriorityOverrides.*)',
      },
      _topLevelActions: {
        type: Array,
        computed: '_computeTopLevelActions(_allActionValues.*, ' +
          '_hiddenActions.*, _overflowActions.*)',
        observer: '_filterPrimaryActions',
      },
      _topLevelPrimaryActions: Array,
      _topLevelSecondaryActions: Array,
      _menuActions: {
        type: Array,
        computed: '_computeMenuActions(_allActionValues.*, ' +
          '_hiddenActions.*, _overflowActions.*)',
      },
      _overflowActions: {
        type: Array,
        value() {
          const value = [
            {
              type: ActionType.CHANGE,
              key: ChangeActions.WIP,
            },
            {
              type: ActionType.CHANGE,
              key: ChangeActions.DELETE,
            },
            {
              type: ActionType.REVISION,
              key: RevisionActions.CHERRYPICK,
            },
            {
              type: ActionType.CHANGE,
              key: ChangeActions.MOVE,
            },
            {
              type: ActionType.REVISION,
              key: RevisionActions.DOWNLOAD,
            },
            {
              type: ActionType.CHANGE,
              key: ChangeActions.IGNORE,
            },
            {
              type: ActionType.CHANGE,
              key: ChangeActions.UNIGNORE,
            },
            {
              type: ActionType.CHANGE,
              key: ChangeActions.REVIEWED,
            },
            {
              type: ActionType.CHANGE,
              key: ChangeActions.UNREVIEWED,
            },
            {
              type: ActionType.CHANGE,
              key: ChangeActions.PRIVATE,
            },
            {
              type: ActionType.CHANGE,
              key: ChangeActions.PRIVATE_DELETE,
            },
            {
              type: ActionType.CHANGE,
              key: ChangeActions.FOLLOW_UP,
            },
          ];
          return value;
        },
      },
      _actionPriorityOverrides: {
        type: Array,
        value() { return []; },
      },
      _additionalActions: {
        type: Array,
        value() { return []; },
      },
      _hiddenActions: {
        type: Array,
        value() { return []; },
      },
      _disabledMenuActions: {
        type: Array,
        value() { return []; },
      },
      // editPatchsetLoaded == "does the current selected patch range have
      // 'edit' as one of either basePatchNum or patchNum".
      editPatchsetLoaded: {
        type: Boolean,
        value: false,
      },
      // editMode == "is edit mode enabled in the file list".
      editMode: {
        type: Boolean,
        value: false,
      },
      editBasedOnCurrentPatchSet: {
        type: Boolean,
        value: true,
      },
      _config: Object,
    };
  }

  static get observers() {
    return [
      '_actionsChanged(actions.*, revisionActions.*, _additionalActions.*)',
      '_changeChanged(change)',
      '_editStatusChanged(editMode, editPatchsetLoaded, ' +
        'editBasedOnCurrentPatchSet, disableEdit, actions.*, change.*)',
    ];
  }

  /** @override */
  created() {
    super.created();
    this.addEventListener('fullscreen-overlay-opened',
        () => this._handleHideBackgroundContent());
    this.addEventListener('fullscreen-overlay-closed',
        () => this._handleShowBackgroundContent());
  }

  /** @override */
  ready() {
    super.ready();
    this.$.jsAPI.addElement(TargetElement.CHANGE_ACTIONS, this);
    this.$.restAPI.getConfig().then(config => {
      this._config = config;
    });
    this._handleLoadingComplete();
  }

  _getSubmitAction(revisionActions) {
    return this._getRevisionAction(revisionActions, 'submit', null);
  }

  _getRebaseAction(revisionActions) {
    return this._getRevisionAction(revisionActions, 'rebase', null);
  }

  _getRevisionAction(revisionActions, actionName, emptyActionValue) {
    if (!revisionActions) {
      return undefined;
    }
    if (revisionActions[actionName] === undefined) {
      // Return null to fire an event when reveisionActions was loaded
      // but doesn't contain actionName. undefined doesn't fire an event
      return emptyActionValue;
    }
    return revisionActions[actionName];
  }

  reload() {
    if (!this.changeNum || !this.latestPatchNum) {
      return Promise.resolve();
    }

    this._loading = true;
    return this._getRevisionActions()
        .then(revisionActions => {
          if (!revisionActions) { return; }

          this.revisionActions = revisionActions;
          this._sendShowRevisionActions({
            change: this.change,
            revisionActions,
          });
          this._handleLoadingComplete();
        })
        .catch(err => {
          this.dispatchEvent(new CustomEvent('show-alert', {
            detail: {message: ERR_REVISION_ACTIONS},
            composed: true, bubbles: true,
          }));
          this._loading = false;
          throw err;
        });
  }

  _handleLoadingComplete() {
    pluginLoader.awaitPluginsLoaded().then(() => this._loading = false);
  }

  _sendShowRevisionActions(detail) {
    this.$.jsAPI.handleEvent(
        EventType.SHOW_REVISION_ACTIONS,
        detail
    );
  }

  _changeChanged() {
    this.reload();
  }

  addActionButton(type, label) {
    if (type !== ActionType.CHANGE && type !== ActionType.REVISION) {
      throw Error(`Invalid action type: ${type}`);
    }
    const action = {
      enabled: true,
      label,
      __type: type,
      __key: ADDITIONAL_ACTION_KEY_PREFIX +
          Math.random().toString(36)
              .substr(2),
    };
    this.push('_additionalActions', action);
    return action.__key;
  }

  removeActionButton(key) {
    const idx = this._indexOfActionButtonWithKey(key);
    if (idx === -1) {
      return;
    }
    this.splice('_additionalActions', idx, 1);
  }

  setActionButtonProp(key, prop, value) {
    this.set([
      '_additionalActions',
      this._indexOfActionButtonWithKey(key),
      prop,
    ], value);
  }

  setActionOverflow(type, key, overflow) {
    if (type !== ActionType.CHANGE && type !== ActionType.REVISION) {
      throw Error(`Invalid action type given: ${type}`);
    }
    const index = this._getActionOverflowIndex(type, key);
    const action = {
      type,
      key,
      overflow,
    };
    if (!overflow && index !== -1) {
      this.splice('_overflowActions', index, 1);
    } else if (overflow) {
      this.push('_overflowActions', action);
    }
  }

  setActionPriority(type, key, priority) {
    if (type !== ActionType.CHANGE && type !== ActionType.REVISION) {
      throw Error(`Invalid action type given: ${type}`);
    }
    const index = this._actionPriorityOverrides
        .findIndex(action => action.type === type && action.key === key);
    const action = {
      type,
      key,
      priority,
    };
    if (index !== -1) {
      this.set('_actionPriorityOverrides', index, action);
    } else {
      this.push('_actionPriorityOverrides', action);
    }
  }

  setActionHidden(type, key, hidden) {
    if (type !== ActionType.CHANGE && type !== ActionType.REVISION) {
      throw Error(`Invalid action type given: ${type}`);
    }

    const idx = this._hiddenActions.indexOf(key);
    if (hidden && idx === -1) {
      this.push('_hiddenActions', key);
    } else if (!hidden && idx !== -1) {
      this.splice('_hiddenActions', idx, 1);
    }
  }

  getActionDetails(action) {
    if (this.revisionActions[action]) {
      return this.revisionActions[action];
    } else if (this.actions[action]) {
      return this.actions[action];
    }
  }

  _indexOfActionButtonWithKey(key) {
    for (let i = 0; i < this._additionalActions.length; i++) {
      if (this._additionalActions[i].__key === key) {
        return i;
      }
    }
    return -1;
  }

  _getRevisionActions() {
    return this.$.restAPI.getChangeRevisionActions(this.changeNum,
        this.latestPatchNum);
  }

  _shouldHideActions(actions, loading) {
    return loading || !actions || !actions.base || !actions.base.length;
  }

  _keyCount(changeRecord) {
    return Object.keys((changeRecord && changeRecord.base) || {}).length;
  }

  _actionsChanged(actionsChangeRecord, revisionActionsChangeRecord,
      additionalActionsChangeRecord) {
    // Polymer 2: check for undefined
    if ([
      actionsChangeRecord,
      revisionActionsChangeRecord,
      additionalActionsChangeRecord,
    ].includes(undefined)) {
      return;
    }

    const additionalActions = (additionalActionsChangeRecord &&
        additionalActionsChangeRecord.base) || [];
    this.hidden = this._keyCount(actionsChangeRecord) === 0 &&
        this._keyCount(revisionActionsChangeRecord) === 0 &&
            additionalActions.length === 0;
    this._actionLoadingMessage = '';
    this._disabledMenuActions = [];

    const revisionActions = revisionActionsChangeRecord.base || {};
    if (Object.keys(revisionActions).length !== 0) {
      if (!revisionActions.download) {
        this.set('revisionActions.download', DOWNLOAD_ACTION);
      }
    }
  }

  /**
   * @param {string=} actionName
   */
  _deleteAndNotify(actionName) {
    if (this.actions && this.actions[actionName]) {
      delete this.actions[actionName];
      // We assign a fake value of 'false' to support Polymer 2
      // see https://github.com/Polymer/polymer/issues/2631
      this.notifyPath('actions.' + actionName, false);
    }
  }

  _editStatusChanged(editMode, editPatchsetLoaded,
      editBasedOnCurrentPatchSet, disableEdit) {
    // Polymer 2: check for undefined
    if ([
      editMode,
      editBasedOnCurrentPatchSet,
      disableEdit,
    ].includes(undefined)) {
      return;
    }

    if (disableEdit) {
      this._deleteAndNotify('publishEdit');
      this._deleteAndNotify('rebaseEdit');
      this._deleteAndNotify('deleteEdit');
      this._deleteAndNotify('stopEdit');
      this._deleteAndNotify('edit');
      return;
    }
    if (this.actions && editPatchsetLoaded) {
      // Only show actions that mutate an edit if an actual edit patch set
      // is loaded.
      if (changeIsOpen(this.change)) {
        if (editBasedOnCurrentPatchSet) {
          if (!this.actions.publishEdit) {
            this.set('actions.publishEdit', PUBLISH_EDIT);
          }
          this._deleteAndNotify('rebaseEdit');
        } else {
          if (!this.actions.rebaseEdit) {
            this.set('actions.rebaseEdit', REBASE_EDIT);
          }
          this._deleteAndNotify('publishEdit');
        }
      }
      if (!this.actions.deleteEdit) {
        this.set('actions.deleteEdit', DELETE_EDIT);
      }
    } else {
      this._deleteAndNotify('publishEdit');
      this._deleteAndNotify('rebaseEdit');
      this._deleteAndNotify('deleteEdit');
    }

    if (this.actions && changeIsOpen(this.change)) {
      // Only show edit button if there is no edit patchset loaded and the
      // file list is not in edit mode.
      if (editPatchsetLoaded || editMode) {
        this._deleteAndNotify('edit');
      } else {
        if (!this.actions.edit) { this.set('actions.edit', EDIT); }
      }
      // Only show STOP_EDIT if edit mode is enabled, but no edit patch set
      // is loaded.
      if (editMode && !editPatchsetLoaded) {
        if (!this.actions.stopEdit) {
          this.set('actions.stopEdit', STOP_EDIT);
        }
      } else {
        this._deleteAndNotify('stopEdit');
      }
    } else {
      // Remove edit button.
      this._deleteAndNotify('edit');
    }
  }

  _getValuesFor(obj) {
    return Object.keys(obj).map(key => obj[key]);
  }

  _getLabelStatus(label) {
    if (label.approved) {
      return LabelStatus.OK;
    } else if (label.rejected) {
      return LabelStatus.REJECT;
    } else if (label.optional) {
      return LabelStatus.OPTIONAL;
    } else {
      return LabelStatus.NEED;
    }
  }

  /**
   * Get highest score for last missing permitted label for current change.
   * Returns null if no labels permitted or more than one label missing.
   *
   * @return {{label: string, score: string}|null}
   */
  _getTopMissingApproval() {
    if (!this.change ||
        !this.change.labels ||
        !this.change.permitted_labels) {
      return null;
    }
    let result;
    for (const label in this.change.labels) {
      if (!(label in this.change.permitted_labels)) {
        continue;
      }
      if (this.change.permitted_labels[label].length === 0) {
        continue;
      }
      const status = this._getLabelStatus(this.change.labels[label]);
      if (status === LabelStatus.NEED) {
        if (result) {
          // More than one label is missing, so it's unclear which to quick
          // approve, return null;
          return null;
        }
        result = label;
      } else if (status === LabelStatus.REJECT ||
          status === LabelStatus.IMPOSSIBLE) {
        return null;
      }
    }
    if (result) {
      const score = this.change.permitted_labels[result].slice(-1)[0];
      const maxScore =
          Object.keys(this.change.labels[result].values).slice(-1)[0];
      if (score === maxScore) {
        // Allow quick approve only for maximal score.
        return {
          label: result,
          score,
        };
      }
    }
    return null;
  }

  hideQuickApproveAction() {
    this._topLevelSecondaryActions =
      this._topLevelSecondaryActions
          .filter(sa => sa.key !== QUICK_APPROVE_ACTION.key);
    this._hideQuickApproveAction = true;
  }

  _getQuickApproveAction() {
    if (this._hideQuickApproveAction) {
      return null;
    }
    const approval = this._getTopMissingApproval();
    if (!approval) {
      return null;
    }
    const action = {...QUICK_APPROVE_ACTION};
    action.label = approval.label + approval.score;
    const review = {
      drafts: 'PUBLISH_ALL_REVISIONS',
      labels: {},
    };
    review.labels[approval.label] = approval.score;
    action.payload = review;
    return action;
  }

  _getActionValues(actionsChangeRecord, primariesChangeRecord,
      additionalActionsChangeRecord, type) {
    if (!actionsChangeRecord || !primariesChangeRecord) { return []; }

    const actions = actionsChangeRecord.base || {};
    const primaryActionKeys = primariesChangeRecord.base || [];
    const result = [];
    const values = this._getValuesFor(
        type === ActionType.CHANGE ? ChangeActions : RevisionActions);
    const pluginActions = [];
    Object.keys(actions).forEach(a => {
      actions[a].__key = a;
      actions[a].__type = type;
      actions[a].__primary = primaryActionKeys.includes(a);
      // Plugin actions always contain ~ in the key.
      if (a.indexOf('~') !== -1) {
        this._populateActionUrl(actions[a]);
        pluginActions.push(actions[a]);
        // Add server-side provided plugin actions to overflow menu.
        this._overflowActions.push({
          type,
          key: a,
        });
        return;
      } else if (!values.includes(a)) {
        return;
      }
      actions[a].label = this._getActionLabel(actions[a]);

      // Triggers a re-render by ensuring object inequality.
      result.push({...actions[a]});
    });

    let additionalActions = (additionalActionsChangeRecord &&
    additionalActionsChangeRecord.base) || [];
    additionalActions = additionalActions
        .filter(a => a.__type === type)
        .map(a => {
          a.__primary = primaryActionKeys.includes(a.__key);
          // Triggers a re-render by ensuring object inequality.
          return {...a};
        });
    return result.concat(additionalActions).concat(pluginActions);
  }

  _populateActionUrl(action) {
    const patchNum =
          action.__type === ActionType.REVISION ? this.latestPatchNum : null;
    this.$.restAPI.getChangeActionURL(
        this.changeNum, patchNum, '/' + action.__key)
        .then(url => action.__url = url);
  }

  /**
   * Given a change action, return a display label that uses the appropriate
   * casing or includes explanatory details.
   */
  _getActionLabel(action) {
    if (action.label === 'Delete') {
      // This label is common within change and revision actions. Make it more
      // explicit to the user.
      return 'Delete change';
    } else if (action.label === 'WIP') {
      return 'Mark as work in progress';
    }
    // Otherwise, just map the name to sentence case.
    return this._toSentenceCase(action.label);
  }

  /**
   * Capitalize the first letter and lowecase all others.
   *
   * @param {string} s
   * @return {string}
   */
  _toSentenceCase(s) {
    if (!s.length) { return ''; }
    return s[0].toUpperCase() + s.slice(1).toLowerCase();
  }

  _computeLoadingLabel(action) {
    return ActionLoadingLabels[action] || 'Working...';
  }

  _canSubmitChange() {
    return this.$.jsAPI.canSubmitChange(this.change,
        this._getRevision(this.change, this.latestPatchNum));
  }

  _getRevision(change, patchNum) {
    for (const rev of Object.values(change.revisions)) {
      if (patchNumEquals(rev._number, patchNum)) {
        return rev;
      }
    }
    return null;
  }

  showRevertDialog() {
    // The search is still broken if there is a " in the topic.
    const query = `submissionid: "${this.change.submission_id}"`;
    /* A chromium plugin expects that the modifyRevertMsg hook will only
    be called after the revert button is pressed, hence we populate the
    revert dialog after revert button is pressed. */
    this.$.restAPI.getChanges('', query)
        .then(changes => {
          this.$.confirmRevertDialog.populate(this.change,
              this.commitMessage, changes);
          this._showActionDialog(this.$.confirmRevertDialog);
        });
  }

  showRevertSubmissionDialog() {
    const query = 'submissionid:' + this.change.submission_id;
    this.$.restAPI.getChanges('', query)
        .then(changes => {
          this.$.confirmRevertSubmissionDialog.
              _populateRevertSubmissionMessage(this.change, changes);
          this._showActionDialog(this.$.confirmRevertSubmissionDialog);
        });
  }

  _handleActionTap(e) {
    e.preventDefault();
    let el = dom(e).localTarget;
    while (el.tagName.toLowerCase() !== 'gr-button') {
      if (!el.parentElement) { return; }
      el = el.parentElement;
    }

    const key = el.getAttribute('data-action-key');
    if (key.startsWith(ADDITIONAL_ACTION_KEY_PREFIX) ||
        key.indexOf('~') !== -1) {
      this.dispatchEvent(new CustomEvent(`${key}-tap`, {
        detail: {node: el},
        composed: true, bubbles: true,
      }));
      return;
    }
    const type = el.getAttribute('data-action-type');
    this._handleAction(type, key);
  }

  _handleOverflowItemTap(e) {
    e.preventDefault();
    const el = dom(e).localTarget;
    const key = e.detail.action.__key;
    if (key.startsWith(ADDITIONAL_ACTION_KEY_PREFIX) ||
        key.indexOf('~') !== -1) {
      this.dispatchEvent(new CustomEvent(`${key}-tap`, {
        detail: {node: el},
        composed: true, bubbles: true,
      }));
      return;
    }
    this._handleAction(e.detail.action.__type, e.detail.action.__key);
  }

  _handleAction(type, key) {
    this.reporting.reportInteraction(`${type}-${key}`);
    switch (type) {
      case ActionType.REVISION:
        this._handleRevisionAction(key);
        break;
      case ActionType.CHANGE:
        this._handleChangeAction(key);
        break;
      default:
        this._fireAction(this._prependSlash(key), this.actions[key], false);
    }
  }

  _handleChangeAction(key) {
    let action;
    switch (key) {
      case ChangeActions.REVERT:
        this.showRevertDialog();
        break;
      case ChangeActions.REVERT_SUBMISSION:
        this.showRevertSubmissionDialog();
        break;
      case ChangeActions.ABANDON:
        this._showActionDialog(this.$.confirmAbandonDialog);
        break;
      case QUICK_APPROVE_ACTION.key:
        action = this._allActionValues.find(o => o.key === key);
        this._fireAction(
            this._prependSlash(key), action, true, action.payload);
        break;
      case ChangeActions.EDIT:
        this._handleEditTap();
        break;
      case ChangeActions.STOP_EDIT:
        this._handleStopEditTap();
        break;
      case ChangeActions.DELETE:
        this._handleDeleteTap();
        break;
      case ChangeActions.DELETE_EDIT:
        this._handleDeleteEditTap();
        break;
      case ChangeActions.FOLLOW_UP:
        this._handleFollowUpTap();
        break;
      case ChangeActions.WIP:
        this._handleWipTap();
        break;
      case ChangeActions.MOVE:
        this._handleMoveTap();
        break;
      case ChangeActions.PUBLISH_EDIT:
        this._handlePublishEditTap();
        break;
      case ChangeActions.REBASE_EDIT:
        this._handleRebaseEditTap();
        break;
      default:
        this._fireAction(this._prependSlash(key), this.actions[key], false);
    }
  }

  _handleRevisionAction(key) {
    switch (key) {
      case RevisionActions.REBASE:
        this._showActionDialog(this.$.confirmRebase);
        this.$.confirmRebase.fetchRecentChanges();
        break;
      case RevisionActions.CHERRYPICK:
        this._handleCherrypickTap();
        break;
      case RevisionActions.DOWNLOAD:
        this._handleDownloadTap();
        break;
      case RevisionActions.SUBMIT:
        if (!this._canSubmitChange()) { return; }
        this._showActionDialog(this.$.confirmSubmitDialog);
        break;
      default:
        this._fireAction(this._prependSlash(key),
            this.revisionActions[key], true);
    }
  }

  _prependSlash(key) {
    return key === '/' ? key : `/${key}`;
  }

  /**
   * _hasKnownChainState set to true true if hasParent is defined (can be
   * either true or false). set to false otherwise.
   */
  _computeChainState(hasParent) {
    this._hasKnownChainState = true;
  }

  _calculateDisabled(action, hasKnownChainState) {
    if (action.__key === 'rebase') {
      // Rebase button is only disabled when change has no parent(s).
      return hasKnownChainState === false;
    }
    return !action.enabled;
  }

  _handleConfirmDialogCancel() {
    this._hideAllDialogs();
  }

  _hideAllDialogs() {
    const dialogEls =
        this.root.querySelectorAll('.confirmDialog');
    for (const dialogEl of dialogEls) { dialogEl.hidden = true; }
    this.$.overlay.close();
  }

  _handleRebaseConfirm(e) {
    const el = this.$.confirmRebase;
    const payload = {base: e.detail.base};
    this.$.overlay.close();
    el.hidden = true;
    this._fireAction('/rebase', this.revisionActions.rebase, true, payload);
  }

  _handleCherrypickConfirm() {
    this._handleCherryPickRestApi(false);
  }

  _handleCherrypickConflictConfirm() {
    this._handleCherryPickRestApi(true);
  }

  _handleCherryPickRestApi(conflicts) {
    const el = this.$.confirmCherrypick;
    if (!el.branch) {
      this.dispatchEvent(new CustomEvent('show-alert', {
        detail: {message: ERR_BRANCH_EMPTY},
        composed: true, bubbles: true,
      }));
      return;
    }
    if (!el.message) {
      this.dispatchEvent(new CustomEvent('show-alert', {
        detail: {message: ERR_COMMIT_EMPTY},
        composed: true, bubbles: true,
      }));
      return;
    }
    this.$.overlay.close();
    el.hidden = true;
    this._fireAction(
        '/cherrypick',
        this.revisionActions.cherrypick,
        true,
        {
          destination: el.branch,
          base: el.baseCommit ? el.baseCommit : null,
          message: el.message,
          allow_conflicts: conflicts,
        }
    );
  }

  _handleMoveConfirm() {
    const el = this.$.confirmMove;
    if (!el.branch) {
      this.dispatchEvent(new CustomEvent('show-alert', {
        detail: {message: ERR_BRANCH_EMPTY},
        composed: true, bubbles: true,
      }));
      return;
    }
    this.$.overlay.close();
    el.hidden = true;
    this._fireAction(
        '/move',
        this.actions.move,
        false,
        {
          destination_branch: el.branch,
          message: el.message,
        }
    );
  }

  _handleRevertDialogConfirm(e) {
    const revertType = e.detail.revertType;
    const message = e.detail.message;
    const el = this.$.confirmRevertDialog;
    this.$.overlay.close();
    el.hidden = true;
    switch (revertType) {
      case REVERT_TYPES.REVERT_SINGLE_CHANGE:
        this._fireAction('/revert', this.actions.revert, false,
            {message});
        break;
      case REVERT_TYPES.REVERT_SUBMISSION:
        this._fireAction('/revert_submission', this.actions.revert_submission,
            false, {message});
        break;
      default:
        console.error('invalid revert type');
    }
  }

  _handleRevertSubmissionDialogConfirm() {
    const el = this.$.confirmRevertSubmissionDialog;
    this.$.overlay.close();
    el.hidden = true;
    this._fireAction('/revert_submission', this.actions.revert_submission,
        false, {message: el.message});
  }

  _handleAbandonDialogConfirm() {
    const el = this.$.confirmAbandonDialog;
    this.$.overlay.close();
    el.hidden = true;
    this._fireAction('/abandon', this.actions.abandon, false,
        {message: el.message});
  }

  _handleCreateFollowUpChange() {
    this.$.createFollowUpChange.handleCreateChange();
    this._handleCloseCreateFollowUpChange();
  }

  _handleCloseCreateFollowUpChange() {
    this.$.overlay.close();
  }

  _handleDeleteConfirm() {
    this._fireAction('/', this.actions[ChangeActions.DELETE], false);
  }

  _handleDeleteEditConfirm() {
    this._hideAllDialogs();

    this._fireAction('/edit', this.actions.deleteEdit, false);
  }

  _handleSubmitConfirm() {
    if (!this._canSubmitChange()) { return; }
    this._hideAllDialogs();
    this._fireAction('/submit', this.revisionActions.submit, true);
  }

  _getActionOverflowIndex(type, key) {
    return this._overflowActions
        .findIndex(action => action.type === type && action.key === key);
  }

  _setLoadingOnButtonWithKey(type, key) {
    this._actionLoadingMessage = this._computeLoadingLabel(key);
    let buttonKey = key;
    // TODO(dhruvsri): clean this up later
    // If key is revert-submission, then button key should be 'revert'
    if (buttonKey === ChangeActions.REVERT_SUBMISSION) {
      // Revert submission button no longer exists
      buttonKey = ChangeActions.REVERT;
    }

    // If the action appears in the overflow menu.
    if (this._getActionOverflowIndex(type, buttonKey) !== -1) {
      this.push('_disabledMenuActions', buttonKey === '/' ? 'delete' :
        buttonKey);
      return function() {
        this._actionLoadingMessage = '';
        this._disabledMenuActions = [];
      }.bind(this);
    }

    // Otherwise it's a top-level action.
    const buttonEl = this.shadowRoot
        .querySelector(`[data-action-key="${buttonKey}"]`);
    buttonEl.setAttribute('loading', true);
    buttonEl.disabled = true;
    return function() {
      this._actionLoadingMessage = '';
      buttonEl.removeAttribute('loading');
      buttonEl.disabled = false;
    }.bind(this);
  }

  /**
   * @param {string} endpoint
   * @param {!Object|undefined} action
   * @param {boolean} revAction
   * @param {!Object|string=} opt_payload
   */
  _fireAction(endpoint, action, revAction, opt_payload) {
    const cleanupFn =
        this._setLoadingOnButtonWithKey(action.__type, action.__key);

    this._send(action.method, opt_payload, endpoint, revAction, cleanupFn,
        action).then(this._handleResponse.bind(this, action));
  }

  _showActionDialog(dialog) {
    this._hideAllDialogs();

    dialog.hidden = false;
    this.$.overlay.open().then(() => {
      if (dialog.resetFocus) {
        dialog.resetFocus();
      }
    });
  }

  // TODO(rmistry): Redo this after
  // https://bugs.chromium.org/p/gerrit/issues/detail?id=4671 is resolved.
  _setLabelValuesOnRevert(newChangeId) {
    const labels = this.$.jsAPI.getLabelValuesPostRevert(this.change);
    if (!labels) { return Promise.resolve(); }
    return this.$.restAPI.saveChangeReview(newChangeId, 'current', {labels});
  }

  _handleResponse(action, response) {
    if (!response) { return; }
    return this.$.restAPI.getResponseObject(response).then(obj => {
      switch (action.__key) {
        case ChangeActions.REVERT:
          this._waitForChangeReachable(obj._number)
              .then(() => this._setLabelValuesOnRevert(obj._number))
              .then(() => {
                GerritNav.navigateToChange(obj);
              });
          break;
        case RevisionActions.CHERRYPICK:
          this._waitForChangeReachable(obj._number).then(() => {
            GerritNav.navigateToChange(obj);
          });
          break;
        case ChangeActions.DELETE:
          if (action.__type === ActionType.CHANGE) {
            GerritNav.navigateToRelativeUrl(GerritNav.getUrlForRoot());
          }
          break;
        case ChangeActions.WIP:
        case ChangeActions.DELETE_EDIT:
        case ChangeActions.PUBLISH_EDIT:
        case ChangeActions.REBASE_EDIT:
        case ChangeActions.REBASE:
        case ChangeActions.SUBMIT:
          this.dispatchEvent(new CustomEvent('reload',
              {
                detail: {clearPatchset: true},
                bubbles: false,
                composed: true,
              }));
          break;
        case ChangeActions.REVERT_SUBMISSION:
          if (!obj.revert_changes || !obj.revert_changes.length) return;
          /* If there is only 1 change then gerrit will automatically
             redirect to that change */
          GerritNav.navigateToSearchQuery('topic: ' +
              obj.revert_changes[0].topic);
          break;
        default:
          this.dispatchEvent(new CustomEvent('reload',
              {
                detail: {action: action.__key, clearPatchset: true},
                bubbles: false,
                composed: true,
              }));
          break;
      }
    });
  }

  _handleShowRevertSubmissionChangesConfirm() {
    this._hideAllDialogs();
  }

  _handleResponseError(action, response, body) {
    if (action && action.__key === RevisionActions.CHERRYPICK) {
      if (response && response.status === 409 &&
          body && !body.allow_conflicts) {
        return this._showActionDialog(
            this.$.confirmCherrypickConflict);
      }
    }
    return response.text().then(errText => {
      this.dispatchEvent(new CustomEvent('show-error', {
        detail: {message: `Could not perform action: ${errText}`},
        composed: true, bubbles: true,
      }));
      if (!errText.startsWith('Change is already up to date')) {
        throw Error(errText);
      }
    });
  }

  /**
   * @param {string} method
   * @param {string|!Object|undefined} payload
   * @param {string} actionEndpoint
   * @param {boolean} revisionAction
   * @param {?Function} cleanupFn
   * @param {!Object|undefined} action
   */
  _send(method, payload, actionEndpoint, revisionAction, cleanupFn, action) {
    const handleError = response => {
      cleanupFn.call(this);
      this._handleResponseError(action, response, payload);
    };
    return fetchChangeUpdates(this.change, this.$.restAPI)
        .then(result => {
          if (!result.isLatest) {
            this.dispatchEvent(new CustomEvent('show-alert', {
              detail: {
                message: 'Cannot set label: a newer patch has been ' +
                  'uploaded to this change.',
                action: 'Reload',
                callback: () => {
                  this.dispatchEvent(new CustomEvent('reload',
                      {
                        detail: {clearPatchset: true},
                        bubbles: false,
                        composed: true,
                      }));
                },
              },
              composed: true, bubbles: true,
            }));

            // Because this is not a network error, call the cleanup function
            // but not the error handler.
            cleanupFn();

            return Promise.resolve();
          }
          const patchNum = revisionAction ? this.latestPatchNum : null;
          return this.$.restAPI.executeChangeAction(this.changeNum, method,
              actionEndpoint, patchNum, payload, handleError)
              .then(response => {
                cleanupFn.call(this);
                return response;
              });
        });
  }

  _handleAbandonTap() {
    this._showActionDialog(this.$.confirmAbandonDialog);
  }

  _handleCherrypickTap() {
    this.$.confirmCherrypick.branch = '';
    const query = `topic: "${this.change.topic}"`;
    const options =
      listChangesOptionsToHex(ListChangesOption.MESSAGES,
          ListChangesOption.ALL_REVISIONS);
    this.$.restAPI.getChanges('', query, undefined, options)
        .then(changes => {
          this.$.confirmCherrypick.updateChanges(changes);
          this._showActionDialog(this.$.confirmCherrypick);
        });
  }

  _handleMoveTap() {
    this.$.confirmMove.branch = '';
    this.$.confirmMove.message = '';
    this._showActionDialog(this.$.confirmMove);
  }

  _handleDownloadTap() {
    this.dispatchEvent(new CustomEvent('download-tap', {
      composed: true, bubbles: false,
    }));
  }

  _handleDeleteTap() {
    this._showActionDialog(this.$.confirmDeleteDialog);
  }

  _handleDeleteEditTap() {
    this._showActionDialog(this.$.confirmDeleteEditDialog);
  }

  _handleFollowUpTap() {
    this._showActionDialog(this.$.createFollowUpDialog);
  }

  _handleWipTap() {
    this._fireAction('/wip', this.actions.wip, false);
  }

  _handlePublishEditTap() {
    // Type of payload is PublishChangeEditInput.
    const payload = {notify: NotifyType.NONE};
    this._fireAction('/edit:publish', this.actions.publishEdit, false, payload);
  }

  _handleRebaseEditTap() {
    this._fireAction('/edit:rebase', this.actions.rebaseEdit, false);
  }

  _handleHideBackgroundContent() {
    this.$.mainContent.classList.add('overlayOpen');
  }

  _handleShowBackgroundContent() {
    this.$.mainContent.classList.remove('overlayOpen');
  }

  /**
   * Merge sources of change actions into a single ordered array of action
   * values.
   *
   * @param {!Array} changeActionsRecord
   * @param {!Array} revisionActionsRecord
   * @param {!Array} primariesRecord
   * @param {!Array} additionalActionsRecord
   * @param {!Object} change The change object.
   * @param {!Object} config server configuration info
   * @return {!Array}
   */
  _computeAllActions(changeActionsRecord, revisionActionsRecord,
      primariesRecord, additionalActionsRecord, change, config) {
    // Polymer 2: check for undefined
    if ([
      changeActionsRecord,
      revisionActionsRecord,
      primariesRecord,
      additionalActionsRecord,
      change,
    ].includes(undefined)) {
      return [];
    }

    const revisionActionValues = this._getActionValues(revisionActionsRecord,
        primariesRecord, additionalActionsRecord, ActionType.REVISION);
    const changeActionValues = this._getActionValues(changeActionsRecord,
        primariesRecord, additionalActionsRecord, ActionType.CHANGE);
    const quickApprove = this._getQuickApproveAction();
    if (quickApprove) {
      changeActionValues.unshift(quickApprove);
    }

    return revisionActionValues
        .concat(changeActionValues)
        .sort(this._actionComparator.bind(this))
        .map(action => {
          if (ACTIONS_WITH_ICONS.has(action.__key)) {
            action.icon = action.__key;
          }
          // TODO(brohlfs): Temporary hack until change 269573 is live in all
          // backends.
          if (action.__key === ChangeActions.READY) {
            action.label = 'Mark as Active';
          }
          // End of hack
          return action;
        })
        .filter(action => !this._shouldSkipAction(action, config));
  }

  _getActionPriority(action) {
    if (action.__type && action.__key) {
      const overrideAction = this._actionPriorityOverrides
          .find(i => i.type === action.__type && i.key === action.__key);

      if (overrideAction !== undefined) {
        return overrideAction.priority;
      }
    }
    if (action.__key === 'review') {
      return ActionPriority.REVIEW;
    } else if (action.__primary) {
      return ActionPriority.PRIMARY;
    } else if (action.__type === ActionType.CHANGE) {
      return ActionPriority.CHANGE;
    } else if (action.__type === ActionType.REVISION) {
      return ActionPriority.REVISION;
    }
    return ActionPriority.DEFAULT;
  }

  /**
   * Sort comparator to define the order of change actions.
   */
  _actionComparator(actionA, actionB) {
    const priorityDelta = this._getActionPriority(actionA) -
        this._getActionPriority(actionB);
    // Sort by the button label if same priority.
    if (priorityDelta === 0) {
      return actionA.label > actionB.label ? 1 : -1;
    } else {
      return priorityDelta;
    }
  }

  _shouldSkipAction(action, config) {
    const skipActionKeys = [...SKIP_ACTION_KEYS];
    const isAttentionSetEnabled = !!config && !!config.change
        && config.change.enable_attention_set;
    if (isAttentionSetEnabled) {
      skipActionKeys.push(...SKIP_ACTION_KEYS_ATTENTION_SET);
    }
    return skipActionKeys.includes(action.__key);
  }

  _computeTopLevelActions(actionRecord, hiddenActionsRecord) {
    const hiddenActions = hiddenActionsRecord.base || [];
    return actionRecord.base.filter(a => {
      const overflow = this._getActionOverflowIndex(a.__type, a.__key) !== -1;
      return !(overflow || hiddenActions.includes(a.__key));
    });
  }

  _filterPrimaryActions(_topLevelActions) {
    this._topLevelPrimaryActions = _topLevelActions.filter(action =>
      action.__primary);
    this._topLevelSecondaryActions = _topLevelActions.filter(action =>
      !action.__primary);
  }

  _computeMenuActions(actionRecord, hiddenActionsRecord) {
    const hiddenActions = hiddenActionsRecord.base || [];
    return actionRecord.base.filter(a => {
      const overflow = this._getActionOverflowIndex(a.__type, a.__key) !== -1;
      return overflow && !hiddenActions.includes(a.__key);
    }).map(action => {
      let key = action.__key;
      if (key === '/') { key = 'delete'; }
      return {
        name: action.label,
        id: `${key}-${action.__type}`,
        action,
        tooltip: action.title,
      };
    });
  }

  _computeRebaseOnCurrent(revisionRebaseAction) {
    if (revisionRebaseAction) {
      return !!revisionRebaseAction.enabled;
    }
    return null;
  }

  /**
   * Occasionally, a change created by a change action is not yet knwon to the
   * API for a brief time. Wait for the given change number to be recognized.
   *
   * Returns a promise that resolves with true if a request is recognized, or
   * false if the change was never recognized after all attempts.
   *
   * @param  {number} changeNum
   * @return {Promise<boolean>}
   */
  _waitForChangeReachable(changeNum) {
    let attempsRemaining = AWAIT_CHANGE_ATTEMPTS;
    return new Promise(resolve => {
      const check = () => {
        attempsRemaining--;
        // Pass a no-op error handler to avoid the "not found" error toast.
        this.$.restAPI.getChange(changeNum, () => {}).then(response => {
          // If the response is 404, the response will be undefined.
          if (response) {
            resolve(true);
            return;
          }

          if (attempsRemaining) {
            this.async(check, AWAIT_CHANGE_TIMEOUT_MS);
          } else {
            resolve(false);
          }
        });
      };
      check();
    });
  }

  _handleEditTap() {
    this.dispatchEvent(new CustomEvent('edit-tap', {bubbles: false}));
  }

  _handleStopEditTap() {
    this.dispatchEvent(new CustomEvent('stop-edit-tap', {bubbles: false}));
  }

  _computeHasTooltip(title) {
    return !!title;
  }

  _computeHasIcon(action) {
    return action.icon ? '' : 'hidden';
  }
}

customElements.define(GrChangeActions.is, GrChangeActions);
