Remove Assignee related rest endpoint.

This is part of the series of changes removing Assignee functionality.
The assignee functionlity was superseded by attention set.

Google-Bug-Id: b/267456422
Release-Notes: skip
Change-Id: I9a5d050b443f90056754137de1367ae99c32876c
diff --git a/Documentation/rest-api-changes.txt b/Documentation/rest-api-changes.txt
index 46724e5..b761687 100644
--- a/Documentation/rest-api-changes.txt
+++ b/Documentation/rest-api-changes.txt
@@ -1125,154 +1125,6 @@
   HTTP/1.1 204 No Content
 ----
 
-[[get-assignee]]
-=== Get Assignee
---
-'GET /changes/link:#change-id[\{change-id\}]/assignee'
---
-
-Retrieves the account of the user assigned to a change.
-
-.Request
-----
-  GET /changes/myProject~master~I8473b95934b5732ac55d26311a706c9c2bde9940/assignee HTTP/1.0
-----
-
-As a response an link:rest-api-accounts.html#account-info[AccountInfo] entity
-describing the assigned account is returned.
-
-.Response
-----
-  HTTP/1.1 200 OK
-  Content-Disposition: attachment
-  Content-Type: application/json; charset=UTF-8
-
-  )]}'
-  {
-    "_account_id": 1000096,
-    "name": "John Doe",
-    "email": "john.doe@example.com",
-    "username": "jdoe"
-  }
-----
-
-If the change has no assignee the response is "`204 No Content`".
-
-[[get-past-assignees]]
-=== Get Past Assignees
---
-'GET /changes/link:#change-id[\{change-id\}]/past_assignees'
---
-
-Returns a list of every user ever assigned to a change, in the order in which
-they were first assigned.
-
-.Request
-----
-  GET /changes/myProject~master~I8473b95934b5732ac55d26311a706c9c2bde9940/past_assignees HTTP/1.0
-----
-
-As a response a list of link:rest-api-accounts.html#account-info[AccountInfo]
-entities is returned.
-
-.Response
-----
-  HTTP/1.1 200 OK
-  Content-Disposition: attachment
-  Content-Type: application/json; charset=UTF-8
-
-  )]}'
-  [
-    {
-      "_account_id": 1000051,
-      "name": "Jane Doe",
-      "email": "jane.doe@example.com",
-      "username": "janed"
-    },
-    {
-      "_account_id": 1000096,
-      "name": "John Doe",
-      "email": "john.doe@example.com",
-      "username": "jdoe"
-    }
-  ]
-
-----
-
-
-[[set-assignee]]
-=== Set Assignee
---
-'PUT /changes/link:#change-id[\{change-id\}]/assignee'
---
-
-Sets the assignee of a change.
-
-The new assignee must be provided in the request body inside a
-link:#assignee-input[AssigneeInput] entity.
-
-.Request
-----
-  PUT /changes/myProject~master~I8473b95934b5732ac55d26311a706c9c2bde9940/assignee HTTP/1.0
-  Content-Type: application/json; charset=UTF-8
-
-  {
-    "assignee": "jdoe"
-  }
-----
-
-As a response an link:rest-api-accounts.html#account-info[AccountInfo] entity
-describing the assigned account is returned.
-
-.Response
-----
-  HTTP/1.1 200 OK
-  Content-Disposition: attachment
-  Content-Type: application/json; charset=UTF-8
-
-  )]}'
-  {
-    "_account_id": 1000096,
-    "name": "John Doe",
-    "email": "john.doe@example.com",
-    "username": "jdoe"
-  }
-----
-
-[[delete-assignee]]
-=== Delete Assignee
---
-'DELETE /changes/link:#change-id[\{change-id\}]/assignee'
---
-
-Deletes the assignee of a change.
-
-
-.Request
-----
-  DELETE /changes/myProject~master~I8473b95934b5732ac55d26311a706c9c2bde9940/assignee HTTP/1.0
-----
-
-As a response an link:rest-api-accounts.html#account-info[AccountInfo] entity
-describing the account of the deleted assignee is returned.
-
-.Response
-----
-  HTTP/1.1 200 OK
-  Content-Disposition: attachment
-  Content-Type: application/json; charset=UTF-8
-
-  )]}'
-  {
-    "_account_id": 1000096,
-    "name": "John Doe",
-    "email": "john.doe@example.com",
-    "username": "jdoe"
-  }
-----
-
-If the change had no assignee the response is "`204 No Content`".
-
 [[get-pure-revert]]
 === Get Pure Revert
 --
@@ -6918,18 +6770,6 @@
 If true, this vote was made after the change was submitted.
 |===========================
 
-[[assignee-input]]
-=== AssigneeInput
-The `AssigneeInput` entity contains the identity of the user to be set as assignee.
-
-[options="header",cols="1,^1,5"]
-|===========================
-|Field Name    ||Description
-|`assignee`     ||
-The link:rest-api-accounts.html#account-id[ID] of one account that
-should be added as assignee.
-|===========================
-
 [[attention-set-info]]
 === AttentionSetInfo
 The `AttentionSetInfo` entity contains details of users that are in
diff --git a/java/com/google/gerrit/extensions/api/changes/AssigneeInput.java b/java/com/google/gerrit/extensions/api/changes/AssigneeInput.java
deleted file mode 100644
index e17e1c9..0000000
--- a/java/com/google/gerrit/extensions/api/changes/AssigneeInput.java
+++ /dev/null
@@ -1,21 +0,0 @@
-// 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.
-
-package com.google.gerrit.extensions.api.changes;
-
-import com.google.gerrit.extensions.restapi.DefaultInput;
-
-public class AssigneeInput {
-  @DefaultInput public String assignee;
-}
diff --git a/java/com/google/gerrit/extensions/api/changes/ChangeApi.java b/java/com/google/gerrit/extensions/api/changes/ChangeApi.java
index 0ebb859..ef61b68 100644
--- a/java/com/google/gerrit/extensions/api/changes/ChangeApi.java
+++ b/java/com/google/gerrit/extensions/api/changes/ChangeApi.java
@@ -347,22 +347,6 @@
   /** Adds a user to the attention set. */
   AccountInfo addToAttentionSet(AttentionSetInput input) throws RestApiException;
 
-  /** Set the assignee of a change. */
-  AccountInfo setAssignee(AssigneeInput input) throws RestApiException;
-
-  /** Get the assignee of a change. */
-  AccountInfo getAssignee() throws RestApiException;
-
-  /** Get all past assignees. */
-  List<AccountInfo> getPastAssignees() throws RestApiException;
-
-  /**
-   * Delete the assignee of a change.
-   *
-   * @return the assignee that was deleted, or null if there was no assignee.
-   */
-  AccountInfo deleteAssignee() throws RestApiException;
-
   /**
    * Get all published comments on a change.
    *
@@ -746,26 +730,6 @@
     }
 
     @Override
-    public AccountInfo setAssignee(AssigneeInput input) throws RestApiException {
-      throw new NotImplementedException();
-    }
-
-    @Override
-    public AccountInfo getAssignee() throws RestApiException {
-      throw new NotImplementedException();
-    }
-
-    @Override
-    public List<AccountInfo> getPastAssignees() throws RestApiException {
-      throw new NotImplementedException();
-    }
-
-    @Override
-    public AccountInfo deleteAssignee() throws RestApiException {
-      throw new NotImplementedException();
-    }
-
-    @Override
     @Deprecated
     public Map<String, List<CommentInfo>> comments() throws RestApiException {
       throw new NotImplementedException();
diff --git a/java/com/google/gerrit/server/ChangeMessagesUtil.java b/java/com/google/gerrit/server/ChangeMessagesUtil.java
index c84c0e7..400da58 100644
--- a/java/com/google/gerrit/server/ChangeMessagesUtil.java
+++ b/java/com/google/gerrit/server/ChangeMessagesUtil.java
@@ -40,8 +40,6 @@
   public static final String TAG_ABANDON = AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "abandon";
   public static final String TAG_CHERRY_PICK_CHANGE =
       AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "cherryPickChange";
-  public static final String TAG_DELETE_ASSIGNEE =
-      AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "deleteAssignee";
   public static final String TAG_DELETE_REVIEWER =
       AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "deleteReviewer";
   public static final String TAG_DELETE_VOTE = AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "deleteVote";
@@ -49,7 +47,6 @@
   public static final String TAG_MOVE = AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "move";
   public static final String TAG_RESTORE = AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "restore";
   public static final String TAG_REVERT = AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "revert";
-  public static final String TAG_SET_ASSIGNEE = AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "setAssignee";
   public static final String TAG_UPDATE_ATTENTION_SET =
       AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "updateAttentionSet";
   public static final String TAG_SET_DESCRIPTION =
diff --git a/java/com/google/gerrit/server/api/changes/ChangeApiImpl.java b/java/com/google/gerrit/server/api/changes/ChangeApiImpl.java
index 66a845a..4fba660 100644
--- a/java/com/google/gerrit/server/api/changes/ChangeApiImpl.java
+++ b/java/com/google/gerrit/server/api/changes/ChangeApiImpl.java
@@ -21,7 +21,6 @@
 import com.google.gerrit.common.Nullable;
 import com.google.gerrit.extensions.api.changes.AbandonInput;
 import com.google.gerrit.extensions.api.changes.ApplyPatchPatchSetInput;
-import com.google.gerrit.extensions.api.changes.AssigneeInput;
 import com.google.gerrit.extensions.api.changes.AttentionSetApi;
 import com.google.gerrit.extensions.api.changes.AttentionSetInput;
 import com.google.gerrit.extensions.api.changes.ChangeApi;
@@ -78,14 +77,11 @@
 import com.google.gerrit.server.restapi.change.Check;
 import com.google.gerrit.server.restapi.change.CheckSubmitRequirement;
 import com.google.gerrit.server.restapi.change.CreateMergePatchSet;
-import com.google.gerrit.server.restapi.change.DeleteAssignee;
 import com.google.gerrit.server.restapi.change.DeleteChange;
 import com.google.gerrit.server.restapi.change.DeletePrivate;
-import com.google.gerrit.server.restapi.change.GetAssignee;
 import com.google.gerrit.server.restapi.change.GetChange;
 import com.google.gerrit.server.restapi.change.GetHashtags;
 import com.google.gerrit.server.restapi.change.GetMetaDiff;
-import com.google.gerrit.server.restapi.change.GetPastAssignees;
 import com.google.gerrit.server.restapi.change.GetPureRevert;
 import com.google.gerrit.server.restapi.change.GetTopic;
 import com.google.gerrit.server.restapi.change.Index;
@@ -97,7 +93,6 @@
 import com.google.gerrit.server.restapi.change.PostHashtags;
 import com.google.gerrit.server.restapi.change.PostPrivate;
 import com.google.gerrit.server.restapi.change.PostReviewers;
-import com.google.gerrit.server.restapi.change.PutAssignee;
 import com.google.gerrit.server.restapi.change.PutMessage;
 import com.google.gerrit.server.restapi.change.PutTopic;
 import com.google.gerrit.server.restapi.change.Rebase;
@@ -159,10 +154,6 @@
   private final AttentionSet attentionSet;
   private final AttentionSetApiImpl.Factory attentionSetApi;
   private final AddToAttentionSet addToAttentionSet;
-  private final PutAssignee putAssignee;
-  private final GetAssignee getAssignee;
-  private final GetPastAssignees getPastAssignees;
-  private final DeleteAssignee deleteAssignee;
   private final Provider<ListChangeComments> listCommentsProvider;
   private final ListChangeRobotComments listChangeRobotComments;
   private final Provider<ListChangeDrafts> listDraftsProvider;
@@ -213,10 +204,6 @@
       AttentionSet attentionSet,
       AttentionSetApiImpl.Factory attentionSetApi,
       AddToAttentionSet addToAttentionSet,
-      PutAssignee putAssignee,
-      GetAssignee getAssignee,
-      GetPastAssignees getPastAssignees,
-      DeleteAssignee deleteAssignee,
       Provider<ListChangeComments> listCommentsProvider,
       ListChangeRobotComments listChangeRobotComments,
       Provider<ListChangeDrafts> listDraftsProvider,
@@ -265,10 +252,6 @@
     this.attentionSet = attentionSet;
     this.attentionSetApi = attentionSetApi;
     this.addToAttentionSet = addToAttentionSet;
-    this.putAssignee = putAssignee;
-    this.getAssignee = getAssignee;
-    this.getPastAssignees = getPastAssignees;
-    this.deleteAssignee = deleteAssignee;
     this.listCommentsProvider = listCommentsProvider;
     this.listChangeRobotComments = listChangeRobotComments;
     this.listDraftsProvider = listDraftsProvider;
@@ -603,46 +586,6 @@
   }
 
   @Override
-  public AccountInfo setAssignee(AssigneeInput input) throws RestApiException {
-    try {
-      return putAssignee.apply(change, input).value();
-    } catch (Exception e) {
-      throw asRestApiException("Cannot set assignee", e);
-    }
-  }
-
-  @Nullable
-  @Override
-  public AccountInfo getAssignee() throws RestApiException {
-    try {
-      Response<AccountInfo> r = getAssignee.apply(change);
-      return r.isNone() ? null : r.value();
-    } catch (Exception e) {
-      throw asRestApiException("Cannot get assignee", e);
-    }
-  }
-
-  @Override
-  public List<AccountInfo> getPastAssignees() throws RestApiException {
-    try {
-      return getPastAssignees.apply(change).value();
-    } catch (Exception e) {
-      throw asRestApiException("Cannot get past assignees", e);
-    }
-  }
-
-  @Nullable
-  @Override
-  public AccountInfo deleteAssignee() throws RestApiException {
-    try {
-      Response<AccountInfo> r = deleteAssignee.apply(change, null);
-      return r.isNone() ? null : r.value();
-    } catch (Exception e) {
-      throw asRestApiException("Cannot delete assignee", e);
-    }
-  }
-
-  @Override
   public CommentsRequest commentsRequest() {
     return new CommentsRequest() {
       @Override
diff --git a/java/com/google/gerrit/server/change/SetAssigneeOp.java b/java/com/google/gerrit/server/change/SetAssigneeOp.java
deleted file mode 100644
index 0757a3e..0000000
--- a/java/com/google/gerrit/server/change/SetAssigneeOp.java
+++ /dev/null
@@ -1,85 +0,0 @@
-// 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.
-
-package com.google.gerrit.server.change;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.gerrit.entities.Change;
-import com.google.gerrit.extensions.restapi.RestApiException;
-import com.google.gerrit.server.ChangeMessagesUtil;
-import com.google.gerrit.server.IdentifiedUser;
-import com.google.gerrit.server.notedb.ChangeUpdate;
-import com.google.gerrit.server.update.BatchUpdateOp;
-import com.google.gerrit.server.update.ChangeContext;
-import com.google.gerrit.server.util.AccountTemplateUtil;
-import com.google.inject.Inject;
-import com.google.inject.assistedinject.Assisted;
-
-public class SetAssigneeOp implements BatchUpdateOp {
-  public interface Factory {
-    SetAssigneeOp create(IdentifiedUser assignee);
-  }
-
-  private final ChangeMessagesUtil cmUtil;
-  private final IdentifiedUser newAssignee;
-  private final IdentifiedUser.GenericFactory userFactory;
-
-  private Change change;
-  private IdentifiedUser oldAssignee;
-
-  @Inject
-  SetAssigneeOp(
-      ChangeMessagesUtil cmUtil,
-      IdentifiedUser.GenericFactory userFactory,
-      @Assisted IdentifiedUser newAssignee) {
-    this.cmUtil = cmUtil;
-    this.userFactory = userFactory;
-    this.newAssignee = requireNonNull(newAssignee, "assignee");
-  }
-
-  @Override
-  public boolean updateChange(ChangeContext ctx) throws RestApiException {
-    change = ctx.getChange();
-    if (newAssignee.getAccountId().equals(change.getAssignee())) {
-      return false;
-    }
-    if (change.getAssignee() != null) {
-      oldAssignee = userFactory.create(change.getAssignee());
-    }
-
-    ChangeUpdate update = ctx.getUpdate(change.currentPatchSetId());
-    // notedb
-    update.setAssignee(newAssignee.getAccountId());
-    // reviewdb
-    change.setAssignee(newAssignee.getAccountId());
-    addMessage(ctx);
-    return true;
-  }
-
-  private void addMessage(ChangeContext ctx) {
-    StringBuilder msg = new StringBuilder();
-    msg.append("Assignee ");
-    if (oldAssignee == null) {
-      msg.append("added: ");
-      msg.append(AccountTemplateUtil.getAccountTemplate(newAssignee.getAccountId()));
-    } else {
-      msg.append("changed from: ");
-      msg.append(AccountTemplateUtil.getAccountTemplate(oldAssignee.getAccountId()));
-      msg.append(" to: ");
-      msg.append(AccountTemplateUtil.getAccountTemplate(newAssignee.getAccountId()));
-    }
-    cmUtil.setChangeMessage(ctx, msg.toString(), ChangeMessagesUtil.TAG_SET_ASSIGNEE);
-  }
-}
diff --git a/java/com/google/gerrit/server/restapi/change/ChangeRestApiModule.java b/java/com/google/gerrit/server/restapi/change/ChangeRestApiModule.java
index f49ee7f..33e6342 100644
--- a/java/com/google/gerrit/server/restapi/change/ChangeRestApiModule.java
+++ b/java/com/google/gerrit/server/restapi/change/ChangeRestApiModule.java
@@ -42,7 +42,6 @@
 import com.google.gerrit.server.change.RebaseChangeOp;
 import com.google.gerrit.server.change.RemoveFromAttentionSetOp;
 import com.google.gerrit.server.change.ReviewerResource;
-import com.google.gerrit.server.change.SetAssigneeOp;
 import com.google.gerrit.server.change.SetCherryPickOp;
 import com.google.gerrit.server.change.SetHashtagsOp;
 import com.google.gerrit.server.change.SetPrivateOp;
@@ -91,10 +90,6 @@
     delete(ATTENTION_SET_ENTRY_KIND).to(RemoveFromAttentionSet.class);
     post(ATTENTION_SET_ENTRY_KIND, "delete").to(RemoveFromAttentionSet.class);
     postOnCollection(ATTENTION_SET_ENTRY_KIND).to(AddToAttentionSet.class);
-    get(CHANGE_KIND, "assignee").to(GetAssignee.class);
-    get(CHANGE_KIND, "past_assignees").to(GetPastAssignees.class);
-    put(CHANGE_KIND, "assignee").to(PutAssignee.class);
-    delete(CHANGE_KIND, "assignee").to(DeleteAssignee.class);
     get(CHANGE_KIND, "hashtags").to(GetHashtags.class);
     get(CHANGE_KIND, "comments").to(ListChangeComments.class);
     get(CHANGE_KIND, "robotcomments").to(ListChangeRobotComments.class);
@@ -220,7 +215,6 @@
     factory(PreviewFix.Factory.class);
     factory(RebaseChangeOp.Factory.class);
     factory(ReviewerResource.Factory.class);
-    factory(SetAssigneeOp.Factory.class);
     factory(SetCherryPickOp.Factory.class);
     factory(SetHashtagsOp.Factory.class);
     factory(SetTopicOp.Factory.class);
diff --git a/java/com/google/gerrit/server/restapi/change/DeleteAssignee.java b/java/com/google/gerrit/server/restapi/change/DeleteAssignee.java
deleted file mode 100644
index 546e657..0000000
--- a/java/com/google/gerrit/server/restapi/change/DeleteAssignee.java
+++ /dev/null
@@ -1,109 +0,0 @@
-// 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.
-
-package com.google.gerrit.server.restapi.change;
-
-import com.google.gerrit.common.Nullable;
-import com.google.gerrit.entities.Account;
-import com.google.gerrit.entities.Change;
-import com.google.gerrit.extensions.common.AccountInfo;
-import com.google.gerrit.extensions.common.Input;
-import com.google.gerrit.extensions.restapi.Response;
-import com.google.gerrit.extensions.restapi.RestApiException;
-import com.google.gerrit.extensions.restapi.RestModifyView;
-import com.google.gerrit.server.ChangeMessagesUtil;
-import com.google.gerrit.server.IdentifiedUser;
-import com.google.gerrit.server.account.AccountLoader;
-import com.google.gerrit.server.account.AccountState;
-import com.google.gerrit.server.change.ChangeResource;
-import com.google.gerrit.server.notedb.ChangeUpdate;
-import com.google.gerrit.server.permissions.ChangePermission;
-import com.google.gerrit.server.permissions.PermissionBackendException;
-import com.google.gerrit.server.update.BatchUpdate;
-import com.google.gerrit.server.update.BatchUpdateOp;
-import com.google.gerrit.server.update.ChangeContext;
-import com.google.gerrit.server.update.UpdateException;
-import com.google.gerrit.server.util.AccountTemplateUtil;
-import com.google.gerrit.server.util.time.TimeUtil;
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
-
-@Singleton
-public class DeleteAssignee implements RestModifyView<ChangeResource, Input> {
-  private final BatchUpdate.Factory updateFactory;
-  private final ChangeMessagesUtil cmUtil;
-  private final IdentifiedUser.GenericFactory userFactory;
-  private final AccountLoader.Factory accountLoaderFactory;
-
-  @Inject
-  DeleteAssignee(
-      BatchUpdate.Factory updateFactory,
-      ChangeMessagesUtil cmUtil,
-      IdentifiedUser.GenericFactory userFactory,
-      AccountLoader.Factory accountLoaderFactory) {
-    this.updateFactory = updateFactory;
-    this.cmUtil = cmUtil;
-    this.userFactory = userFactory;
-    this.accountLoaderFactory = accountLoaderFactory;
-  }
-
-  @Override
-  public Response<AccountInfo> apply(ChangeResource rsrc, Input input)
-      throws RestApiException, UpdateException, PermissionBackendException {
-    rsrc.permissions().check(ChangePermission.EDIT_ASSIGNEE);
-
-    try (BatchUpdate bu = updateFactory.create(rsrc.getProject(), rsrc.getUser(), TimeUtil.now())) {
-      Op op = new Op();
-      bu.addOp(rsrc.getChange().getId(), op);
-      bu.execute();
-      Account.Id deletedAssignee = op.getDeletedAssignee();
-      return deletedAssignee == null
-          ? Response.none()
-          : Response.ok(accountLoaderFactory.create(true).fillOne(deletedAssignee));
-    }
-  }
-
-  private class Op implements BatchUpdateOp {
-    private Change change;
-    private AccountState deletedAssignee;
-
-    @Override
-    public boolean updateChange(ChangeContext ctx) throws RestApiException {
-      change = ctx.getChange();
-      ChangeUpdate update = ctx.getUpdate(change.currentPatchSetId());
-      Account.Id currentAssigneeId = change.getAssignee();
-      if (currentAssigneeId == null) {
-        return false;
-      }
-      IdentifiedUser deletedAssigneeUser = userFactory.create(currentAssigneeId);
-      deletedAssignee = deletedAssigneeUser.state();
-      update.removeAssignee();
-      addMessage(ctx, deletedAssigneeUser);
-      return true;
-    }
-
-    @Nullable
-    public Account.Id getDeletedAssignee() {
-      return deletedAssignee != null ? deletedAssignee.account().id() : null;
-    }
-
-    private void addMessage(ChangeContext ctx, IdentifiedUser deletedAssignee) {
-      cmUtil.setChangeMessage(
-          ctx,
-          "Assignee deleted: "
-              + AccountTemplateUtil.getAccountTemplate(deletedAssignee.getAccountId()),
-          ChangeMessagesUtil.TAG_DELETE_ASSIGNEE);
-    }
-  }
-}
diff --git a/java/com/google/gerrit/server/restapi/change/GetAssignee.java b/java/com/google/gerrit/server/restapi/change/GetAssignee.java
deleted file mode 100644
index a5820bf..0000000
--- a/java/com/google/gerrit/server/restapi/change/GetAssignee.java
+++ /dev/null
@@ -1,45 +0,0 @@
-// 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.
-
-package com.google.gerrit.server.restapi.change;
-
-import com.google.gerrit.entities.Account;
-import com.google.gerrit.extensions.common.AccountInfo;
-import com.google.gerrit.extensions.restapi.Response;
-import com.google.gerrit.extensions.restapi.RestReadView;
-import com.google.gerrit.server.account.AccountLoader;
-import com.google.gerrit.server.change.ChangeResource;
-import com.google.gerrit.server.permissions.PermissionBackendException;
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
-import java.util.Optional;
-
-@Singleton
-public class GetAssignee implements RestReadView<ChangeResource> {
-  private final AccountLoader.Factory accountLoaderFactory;
-
-  @Inject
-  GetAssignee(AccountLoader.Factory accountLoaderFactory) {
-    this.accountLoaderFactory = accountLoaderFactory;
-  }
-
-  @Override
-  public Response<AccountInfo> apply(ChangeResource rsrc) throws PermissionBackendException {
-    Optional<Account.Id> assignee = Optional.ofNullable(rsrc.getChange().getAssignee());
-    if (assignee.isPresent()) {
-      return Response.ok(accountLoaderFactory.create(true).fillOne(assignee.get()));
-    }
-    return Response.none();
-  }
-}
diff --git a/java/com/google/gerrit/server/restapi/change/GetPastAssignees.java b/java/com/google/gerrit/server/restapi/change/GetPastAssignees.java
deleted file mode 100644
index c1c9a34..0000000
--- a/java/com/google/gerrit/server/restapi/change/GetPastAssignees.java
+++ /dev/null
@@ -1,54 +0,0 @@
-// 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.
-
-package com.google.gerrit.server.restapi.change;
-
-import static java.util.stream.Collectors.toList;
-
-import com.google.gerrit.entities.Account;
-import com.google.gerrit.extensions.common.AccountInfo;
-import com.google.gerrit.extensions.restapi.Response;
-import com.google.gerrit.extensions.restapi.RestReadView;
-import com.google.gerrit.server.account.AccountLoader;
-import com.google.gerrit.server.change.ChangeResource;
-import com.google.gerrit.server.permissions.PermissionBackendException;
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-
-@Singleton
-public class GetPastAssignees implements RestReadView<ChangeResource> {
-  private final AccountLoader.Factory accountLoaderFactory;
-
-  @Inject
-  GetPastAssignees(AccountLoader.Factory accountLoaderFactory) {
-    this.accountLoaderFactory = accountLoaderFactory;
-  }
-
-  @Override
-  public Response<List<AccountInfo>> apply(ChangeResource rsrc) throws PermissionBackendException {
-
-    Set<Account.Id> pastAssignees = rsrc.getNotes().load().getPastAssignees();
-    if (pastAssignees == null) {
-      return Response.ok(Collections.emptyList());
-    }
-
-    AccountLoader accountLoader = accountLoaderFactory.create(true);
-    List<AccountInfo> infos = pastAssignees.stream().map(accountLoader::get).collect(toList());
-    accountLoader.fill();
-    return Response.ok(infos);
-  }
-}
diff --git a/java/com/google/gerrit/server/restapi/change/PutAssignee.java b/java/com/google/gerrit/server/restapi/change/PutAssignee.java
deleted file mode 100644
index d41620e..0000000
--- a/java/com/google/gerrit/server/restapi/change/PutAssignee.java
+++ /dev/null
@@ -1,133 +0,0 @@
-// 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.
-
-package com.google.gerrit.server.restapi.change;
-
-import com.google.common.base.Strings;
-import com.google.gerrit.extensions.api.changes.AssigneeInput;
-import com.google.gerrit.extensions.api.changes.NotifyHandling;
-import com.google.gerrit.extensions.api.changes.ReviewerInput;
-import com.google.gerrit.extensions.client.ReviewerState;
-import com.google.gerrit.extensions.common.AccountInfo;
-import com.google.gerrit.extensions.restapi.AuthException;
-import com.google.gerrit.extensions.restapi.BadRequestException;
-import com.google.gerrit.extensions.restapi.Response;
-import com.google.gerrit.extensions.restapi.RestApiException;
-import com.google.gerrit.extensions.restapi.RestModifyView;
-import com.google.gerrit.extensions.webui.UiAction;
-import com.google.gerrit.server.IdentifiedUser;
-import com.google.gerrit.server.ReviewerSet;
-import com.google.gerrit.server.account.AccountLoader;
-import com.google.gerrit.server.account.AccountResolver;
-import com.google.gerrit.server.approval.ApprovalsUtil;
-import com.google.gerrit.server.change.ChangeResource;
-import com.google.gerrit.server.change.ReviewerModifier;
-import com.google.gerrit.server.change.ReviewerModifier.ReviewerModification;
-import com.google.gerrit.server.change.SetAssigneeOp;
-import com.google.gerrit.server.permissions.ChangePermission;
-import com.google.gerrit.server.permissions.PermissionBackend;
-import com.google.gerrit.server.permissions.PermissionBackendException;
-import com.google.gerrit.server.update.BatchUpdate;
-import com.google.gerrit.server.update.UpdateException;
-import com.google.gerrit.server.util.time.TimeUtil;
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
-import java.io.IOException;
-import org.eclipse.jgit.errors.ConfigInvalidException;
-
-@Singleton
-public class PutAssignee
-    implements RestModifyView<ChangeResource, AssigneeInput>, UiAction<ChangeResource> {
-
-  private final BatchUpdate.Factory updateFactory;
-  private final AccountResolver accountResolver;
-  private final SetAssigneeOp.Factory assigneeFactory;
-  private final ReviewerModifier reviewerModifier;
-  private final AccountLoader.Factory accountLoaderFactory;
-  private final PermissionBackend permissionBackend;
-  private final ApprovalsUtil approvalsUtil;
-
-  @Inject
-  PutAssignee(
-      BatchUpdate.Factory updateFactory,
-      AccountResolver accountResolver,
-      SetAssigneeOp.Factory assigneeFactory,
-      ReviewerModifier reviewerModifier,
-      AccountLoader.Factory accountLoaderFactory,
-      PermissionBackend permissionBackend,
-      ApprovalsUtil approvalsUtil) {
-    this.updateFactory = updateFactory;
-    this.accountResolver = accountResolver;
-    this.assigneeFactory = assigneeFactory;
-    this.reviewerModifier = reviewerModifier;
-    this.accountLoaderFactory = accountLoaderFactory;
-    this.permissionBackend = permissionBackend;
-    this.approvalsUtil = approvalsUtil;
-  }
-
-  @Override
-  public Response<AccountInfo> apply(ChangeResource rsrc, AssigneeInput input)
-      throws RestApiException, UpdateException, IOException, PermissionBackendException,
-          ConfigInvalidException {
-    rsrc.permissions().check(ChangePermission.EDIT_ASSIGNEE);
-
-    input.assignee = Strings.nullToEmpty(input.assignee).trim();
-    if (input.assignee.isEmpty()) {
-      throw new BadRequestException("missing assignee field");
-    }
-
-    IdentifiedUser assignee = accountResolver.resolve(input.assignee).asUniqueUser();
-    try {
-      permissionBackend
-          .absentUser(assignee.getAccountId())
-          .change(rsrc.getNotes())
-          .check(ChangePermission.READ);
-    } catch (AuthException e) {
-      throw new AuthException("read not permitted for " + input.assignee, e);
-    }
-
-    try (BatchUpdate bu =
-        updateFactory.create(rsrc.getChange().getProject(), rsrc.getUser(), TimeUtil.now())) {
-      SetAssigneeOp op = assigneeFactory.create(assignee);
-      bu.addOp(rsrc.getId(), op);
-
-      ReviewerSet currentReviewers = approvalsUtil.getReviewers(rsrc.getNotes());
-      if (!currentReviewers.all().contains(assignee.getAccountId())) {
-        ReviewerModification reviewersAddition = addAssigneeAsCC(rsrc, input.assignee);
-        reviewersAddition.op.suppressEmail();
-        bu.addOp(rsrc.getId(), reviewersAddition.op);
-      }
-
-      bu.execute();
-      return Response.ok(accountLoaderFactory.create(true).fillOne(assignee.getAccountId()));
-    }
-  }
-
-  private ReviewerModification addAssigneeAsCC(ChangeResource rsrc, String assignee)
-      throws IOException, PermissionBackendException, ConfigInvalidException {
-    ReviewerInput reviewerInput = new ReviewerInput();
-    reviewerInput.reviewer = assignee;
-    reviewerInput.state = ReviewerState.CC;
-    reviewerInput.confirmed = true;
-    reviewerInput.notify = NotifyHandling.NONE;
-    return reviewerModifier.prepare(rsrc.getNotes(), rsrc.getUser(), reviewerInput, false);
-  }
-
-  @Override
-  public UiAction.Description getDescription(ChangeResource rsrc) {
-    return new UiAction.Description()
-        .setLabel("Edit Assignee")
-        .setVisible(rsrc.permissions().testCond(ChangePermission.EDIT_ASSIGNEE));
-  }
-}
diff --git a/javatests/com/google/gerrit/acceptance/rest/binding/ChangesRestApiBindingsIT.java b/javatests/com/google/gerrit/acceptance/rest/binding/ChangesRestApiBindingsIT.java
index 2d663df..27bd6b9 100644
--- a/javatests/com/google/gerrit/acceptance/rest/binding/ChangesRestApiBindingsIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/binding/ChangesRestApiBindingsIT.java
@@ -65,10 +65,6 @@
           RestCall.get("/changes/%s/drafts"),
           RestCall.get("/changes/%s/attention"),
           RestCall.post("/changes/%s/attention"),
-          RestCall.get("/changes/%s/assignee"),
-          RestCall.get("/changes/%s/past_assignees"),
-          RestCall.put("/changes/%s/assignee"),
-          RestCall.delete("/changes/%s/assignee"),
           RestCall.post("/changes/%s/private"),
           RestCall.post("/changes/%s/private.delete"),
           RestCall.delete("/changes/%s/private"),